Cataclysm BN
map Class Reference

Manage and cache data about a part of the map. More...

#include <map.h>

Inheritance diagram for map:
tinymap fake_map

Classes

struct  apparent_light_info
 

Public Member Functions

 map (int mapsize=MAPSIZE, bool zlev=false)
 
 map (bool zlev)
 
virtual ~map ()
 
mapoperator= (const map &)=delete
 
mapoperator= (map &&)
 
void set_transparency_cache_dirty (const int zlev)
 Sets a dirty flag on the a given cache. More...
 
void set_transparency_cache_dirty (const tripoint &p)
 
void set_seen_cache_dirty (const tripoint change_location)
 
void set_seen_cache_dirty (const int zlevel)
 
void set_outside_cache_dirty (const int zlev)
 
void set_floor_cache_dirty (const int zlev)
 
void set_suspension_cache_dirty (const int zlev)
 
void set_pathfinding_cache_dirty (int zlev)
 
void set_memory_seen_cache_dirty (const tripoint &p)
 
void invalidate_map_cache (const int zlev)
 
bool check_seen_cache (const tripoint &p) const
 
bool check_and_set_seen_cache (const tripoint &p) const
 
void on_vehicle_moved (int smz)
 Callback invoked when a vehicle has moved. More...
 
lit_level apparent_light_at (const tripoint &p, const visibility_variables &cache) const
 Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc. More...
 
visibility_type get_visibility (lit_level ll, const visibility_variables &cache) const
 
std::tuple< maptile, maptile, maptileget_wind_blockers (const int &winddirection, const tripoint &pos)
 
void draw (const catacurses::window &w, const tripoint &center)
 Draw a visible part of the map into w. More...
 
void drawsq (const catacurses::window &w, const tripoint &p, const drawsq_params &params) const
 Draw the map tile at the given coordinate. More...
 
void save ()
 Add currently loaded submaps (in grid) to the mapbuffer. More...
 
void load (const tripoint &w, bool update_vehicles, bool pump_events=false)
 Load submaps into grid. More...
 
void load (const tripoint_abs_sm &w, bool update_vehicles, bool pump_events=false)
 
void shift (point s)
 Shift the map along the vector s. More...
 
void vertical_shift (int newz)
 Moves the map vertically to (not by!) newz. More...
 
void clear_spawns ()
 
void clear_traps ()
 
maptile maptile_at (const tripoint &p) const
 
maptile maptile_at (const tripoint &p)
 
int move_cost (const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
 Calculate the cost to move past the tile at p. More...
 
int move_cost (point p, const vehicle *ignored_vehicle=nullptr) const
 
bool impassable (const tripoint &p) const
 
bool impassable (point p) const
 
bool passable (const tripoint &p) const
 
bool passable (point p) const
 
bool is_wall_adjacent (const tripoint &center) const
 
int move_cost_ter_furn (const tripoint &p) const
 Similar behavior to move_cost(), but ignores vehicles. More...
 
int move_cost_ter_furn (point p) const
 
bool impassable_ter_furn (const tripoint &p) const
 
bool passable_ter_furn (const tripoint &p) const
 
int combined_movecost (const tripoint &from, const tripoint &to, const vehicle *ignored_vehicle=nullptr, int modifier=0, bool flying=false, bool via_ramp=false) const
 Cost to move out of one tile and into the next. More...
 
bool valid_move (const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
 Returns true if a creature could walk from from to to in one step. More...
 
double ranged_target_size (const tripoint &p) const
 Size of map objects at p for purposes of ranged combat. More...
 
bool sees (const tripoint &F, const tripoint &T, int range) const
 Returns whether F sees T with a view range of range. More...
 
int obstacle_coverage (const tripoint &loc1, const tripoint &loc2) const
 Returns coverage of target in relation to the observer. More...
 
int coverage (const tripoint &p) const
 Returns coverage value of the tile. More...
 
bool clear_path (const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
 Check whether there's a direct line of sight between F and T with the additional movecost restraints. More...
 
bool obstructed_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent. More...
 
bool obscured_by_vehicle_rotation (const tripoint &from, const tripoint &to) const
 Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent. More...
 
void reachable_flood_steps (std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
 Populates a vector of points that are reachable within a number of steps from a point. More...
 
std::vector< tripointfind_clear_path (const tripoint &source, const tripoint &destination) const
 Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one. More...
 
bool accessible_items (const tripoint &t) const
 Check whether the player can access the items located . More...
 
std::vector< tripointget_dir_circle (const tripoint &f, const tripoint &t) const
 Calculate next search points surrounding the current position. More...
 
std::vector< tripointroute (const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
 Calculate the best path using A*. More...
 
VehicleList get_vehicles ()
 
void add_vehicle_to_cache (vehicle *)
 
void clear_vehicle_point_from_cache (vehicle *veh, const tripoint &pt)
 
void update_vehicle_cache (vehicle *, int old_zlevel)
 
void reset_vehicle_cache ()
 
void clear_vehicle_cache ()
 
void clear_vehicle_list (int zlev)
 
void update_vehicle_list (const submap *to, int zlev)
 
bool check_vehicle_zones (int zlev)
 
std::vector< zone_data * > get_vehicle_zones (int zlev)
 
void register_vehicle_zone (vehicle *, int zlev)
 
bool deregister_vehicle_zone (zone_data &zone)
 
std::unique_ptr< vehicledetach_vehicle (vehicle *veh)
 
void destroy_vehicle (vehicle *veh)
 
void vehmove ()
 
bool vehproceed (VehicleList &vehicle_list)
 
VehicleList get_vehicles (const tripoint &start, const tripoint &end)
 
optional_vpart_position veh_at (const tripoint &p) const
 Checks if tile is occupied by vehicle and by which part. More...
 
optional_vpart_position veh_at (const tripoint_abs_ms &p) const
 
vehicleveh_at_internal (const tripoint &p, int &part_num)
 
const vehicleveh_at_internal (const tripoint &p, int &part_num) const
 
void board_vehicle (const tripoint &p, player *pl)
 
void unboard_vehicle (const vpart_reference &, Character *passenger, bool dead_passenger=false)
 
void unboard_vehicle (const tripoint &p, bool dead_passenger=false)
 
bool displace_vehicle (vehicle &veh, const tripoint &dp)
 
void shift_vehicle_z (vehicle &veh, int z_shift)
 
bool displace_water (const tripoint &dp)
 
float vehicle_wheel_traction (const vehicle &veh, bool ignore_movement_modifiers=false) const
 
float vehicle_vehicle_collision (vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
 
units::angle shake_vehicle (vehicle &veh, int velocity_before, units::angle direction)
 
vehiclemove_vehicle (vehicle &veh, const tripoint &dp, const tileray &facing)
 
void set (const tripoint &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
void set (point p, const ter_id &new_terrain, const furn_id &new_furniture)
 
std::string name (const tripoint &p)
 
std::string name (point p)
 
std::string disp_name (const tripoint &p)
 
std::string obstacle_name (const tripoint &p)
 Returns the name of the obstacle at p that might be blocking movement/projectiles/etc. More...
 
bool has_furn (const tripoint &p) const
 
bool has_furn (point p) const
 
furn_id furn (const tripoint &p) const
 
furn_id furn (point p) const
 
void furn_set (const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
 Sets the furniture at given position. More...
 
void furn_set (point p, const furn_id &new_furniture)
 
std::string furnname (const tripoint &p)
 
std::string furnname (point p)
 
bool can_move_furniture (const tripoint &pos, player *p=nullptr)
 
ter_id ter (const tripoint &p) const
 
ter_id ter (point p) const
 
uint8_t get_known_connections (const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
 
const harvest_idget_harvest (const tripoint &p) const
 Returns the full harvest list, for spawning. More...
 
const std::set< std::string > & get_harvest_names (const tripoint &p) const
 Returns names of the items that would be dropped. More...
 
ter_id get_ter_transforms_into (const tripoint &p) const
 
furn_id get_furn_transforms_into (const tripoint &p) const
 
bool ter_set (const tripoint &p, const ter_id &new_terrain)
 
bool ter_set (point p, const ter_id &new_terrain)
 
std::string tername (const tripoint &p) const
 
std::string tername (point p) const
 
bool has_nearby_fire (const tripoint &p, int radius=1)
 
bool has_nearby_table (const tripoint &p, int radius=1)
 Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating. More...
 
bool has_nearby_chair (const tripoint &p, int radius=1)
 Check whether a chair or vehicle seat is nearby. More...
 
bool sees_some_items (const tripoint &p, const Creature &who) const
 Check if creature can see some items at p. More...
 
bool sees_some_items (const tripoint &p, const tripoint &from) const
 
bool could_see_items (const tripoint &p, const Creature &who) const
 Check if the creature could see items at p if there were any items. More...
 
bool could_see_items (const tripoint &p, const tripoint &from) const
 
bool has_items (const tripoint &p) const
 Checks for existence of items. More...
 
void examine (Character &p, const tripoint &pos)
 Calls the examine function of furniture or terrain at given tile, for given character. More...
 
bool is_harvestable (const tripoint &pos) const
 Returns true if point at pos is harvestable right now, with no extra tools. More...
 
std::string features (const tripoint &p)
 
std::string features (point p)
 
bool has_flag (const std::string &flag, const tripoint &p) const
 
bool has_flag (const std::string &flag, point p) const
 
bool can_put_items (const tripoint &p) const
 
bool can_put_items (point p) const
 
bool can_put_items_ter_furn (const tripoint &p) const
 
bool can_put_items_ter_furn (point p) const
 
bool has_flag_ter (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter (const std::string &flag, point p) const
 
bool has_flag_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn (const std::string &flag, point p) const
 
bool has_flag_vpart (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn_or_vpart (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, point p) const
 
bool has_flag (ter_bitflags flag, const tripoint &p) const
 
bool has_flag (ter_bitflags flag, point p) const
 
bool has_flag_ter (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter (ter_bitflags flag, point p) const
 
bool has_flag_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_furn (ter_bitflags flag, point p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, point p) const
 
bool is_bashable (const tripoint &p, bool allow_floor=false) const
 Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p. More...
 
bool is_bashable (point p) const
 
bool is_bashable_ter (const tripoint &p, bool allow_floor=false) const
 Returns true if the terrain at p is bashable. More...
 
bool is_bashable_ter (point p) const
 
bool is_bashable_furn (const tripoint &p) const
 Returns true if the furniture at p is bashable. More...
 
bool is_bashable_furn (point p) const
 
bool is_bashable_ter_furn (const tripoint &p, bool allow_floor=false) const
 Returns true if the furniture or terrain at p is bashable. More...
 
bool is_bashable_ter_furn (point p) const
 
int bash_strength (const tripoint &p, bool allow_floor=false) const
 Returns max_str of the furniture or terrain at p. More...
 
int bash_strength (point p) const
 
int bash_resistance (const tripoint &p, bool allow_floor=false) const
 Returns min_str of the furniture or terrain at p. More...
 
int bash_resistance (point p) const
 
int bash_rating (int str, const tripoint &p, bool allow_floor=false) const
 Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down. More...
 
int bash_rating (const int str, point p) const
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, const ter_id &floor_type, bool overwrite=false)
 Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true. More...
 
void make_rubble (const tripoint &p, const furn_id &rubble_type)
 
void make_rubble (const tripoint &p)
 
bool is_outside (const tripoint &p) const
 
bool is_outside (point p) const
 
bool is_divable (const tripoint &p) const
 Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing). More...
 
bool is_divable (point p) const
 
bool is_water_shallow_current (const tripoint &p) const
 
bool is_water_shallow_current (point p) const
 
bool is_last_ter_wall (bool no_furn, point p, point max, direction dir) const
 Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST. More...
 
bool tinder_at (const tripoint &p)
 Checks if there are any tinder flagged items on the tile. More...
 
bool flammable_items_at (const tripoint &p, int threshold=0)
 Checks if there are any flammable items on the tile. More...
 
bool is_flammable (const tripoint &p)
 Returns true if there is a flammable item or field or the furn/terrain is flammable at p. More...
 
point random_outdoor_tile ()
 
void draw_line_ter (const ter_id &type, point p1, point p2)
 
void draw_line_furn (const furn_id &type, point p1, point p2)
 
void draw_fill_background (const ter_id &type)
 
void draw_fill_background (ter_id(*f)())
 
void draw_fill_background (const weighted_int_list< ter_id > &f)
 
void draw_square_ter (const ter_id &type, point p1, point p2)
 
void draw_square_furn (const furn_id &type, point p1, point p2)
 
void draw_square_ter (ter_id(*f)(), point p1, point p2)
 
void draw_square_ter (const weighted_int_list< ter_id > &f, point p1, point p2)
 
void draw_rough_circle_ter (const ter_id &type, point p, int rad)
 
void draw_rough_circle_furn (const furn_id &type, point p, int rad)
 
void draw_circle_ter (const ter_id &type, const rl_vec2d &p, double rad)
 
void draw_circle_ter (const ter_id &type, point p, int rad)
 
void draw_circle_furn (const furn_id &type, point p, int rad)
 
void add_corpse (const tripoint &p)
 
void translate (const ter_id &from, const ter_id &to)
 
void translate_radius (const ter_id &from, const ter_id &to, float radi, const tripoint &p, bool same_submap=false, bool toggle_between=false)
 
bool close_door (const tripoint &p, bool inside, bool check_only)
 
bool open_door (const tripoint &p, bool inside, bool check_only=false)
 
void batter (const tripoint &p, int power, int tries=1, bool silent=false)
 bash a square for a set number of times at set power. More...
 
void destroy (const tripoint &p, bool silent=false)
 Keeps bashing a square until it can't be bashed anymore. More...
 
void destroy_furn (const tripoint &p, bool silent=false)
 Keeps bashing a square until there is no more furniture. More...
 
void crush (const tripoint &p)
 
void shoot (const tripoint &p, projectile &proj, bool hit_items)
 
int collapse_check (const tripoint &p)
 Checks if a square should collapse, returns the X for the one_in(X) collapse chance. More...
 
void collapse_at (const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
 Causes a collapse at p, such as from destroying a wall. More...
 
void propagate_suspension_check (const tripoint &point)
 Checks surrounding tiles for suspension, and has them check for collapse. More...
 
void collapse_invalid_suspension (const tripoint &point)
 Triggers a recursive collapse of suspended tiles based on their support validity. More...
 
bool is_suspension_valid (const tripoint &point)
 Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid. More...
 
void smash_trap (const tripoint &p, const int power, const std::string &cause_message)
 Tries to smash the trap at the given tripoint. More...
 
void smash_items (const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
 Tries to smash the items at the given tripoint. More...
 
bash_results bash (const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
 Returns a pair where first is whether anything was smashed and second is if it was destroyed. More...
 
bash_results bash_vehicle (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_furn (const tripoint &p, const bash_params &params)
 
bool hit_with_acid (const tripoint &p)
 
bool hit_with_fire (const tripoint &p)
 
bool has_adjacent_furniture_with (const tripoint &p, const std::function< bool(const furn_t &)> &filter)
 Returns true if there is furniture for which filter returns true in a 1 tile radius of p. More...
 
bool mop_spills (const tripoint &p)
 Remove moppable fields/items at this location. More...
 
void decay_fields_and_scent (const time_duration &amount)
 Moved here from weather.cpp for speed. More...
 
std::string get_signage (const tripoint &p) const
 
void set_signage (const tripoint &p, const std::string &message) const
 
void delete_signage (const tripoint &p) const
 
int get_radiation (const tripoint &p) const
 
void set_radiation (const tripoint &p, int value)
 
void set_radiation (point p, const int value)
 
void adjust_radiation (const tripoint &p, int delta)
 Increment the radiation in the given tile by the given delta (decrement it if delta is negative) More...
 
void adjust_radiation (point p, const int delta)
 
int get_temperature (const tripoint &p) const
 
void set_temperature (const tripoint &p, int temperature)
 
void set_temperature (point p, int new_temperature)
 
std::vector< tripointcheck_submap_active_item_consistency ()
 
map_stack i_at (const tripoint &p)
 
map_stack i_at (point p)
 
item water_from (const tripoint &p)
 
void i_clear (const tripoint &p)
 
void i_clear (point p)
 
map_stack::iterator i_rem (const tripoint &p, map_stack::const_iterator it)
 
map_stack::iterator i_rem (point location, map_stack::const_iterator it)
 
void i_rem (const tripoint &p, item *it)
 
void i_rem (point p, item *it)
 
void spawn_artifact (const tripoint &p)
 
void spawn_natural_artifact (const tripoint &p, artifact_natural_property prop)
 
void spawn_item (const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (point p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const tripoint &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (point p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
units::volume max_volume (const tripoint &p)
 
units::volume free_volume (const tripoint &p)
 
units::volume stored_volume (const tripoint &p)
 
itemadd_item_or_charges (const tripoint &pos, item obj, bool overflow=true)
 Adds an item to map tile or stacks charges. More...
 
itemadd_item_or_charges (point p, item obj, bool overflow=true)
 
itemadd_item (const tripoint &p, item new_item)
 Place an item on the map, despite the parameter name, this is not necessarily a new item. More...
 
void add_item (point p, item new_item)
 
itemspawn_an_item (const tripoint &p, item new_item, int charges, int damlevel)
 
void spawn_an_item (point p, item new_item, int charges, int damlevel)
 
void make_active (item_location &loc)
 Update an item's active status, for example when adding hot or perishable liquid to a container. More...
 
void update_lum (item_location &loc, bool add)
 Update luminosity before and after item's transformation. More...
 

Static Public Member Functions

static apparent_light_info apparent_light_helper (const level_cache &map_cache, const tripoint &p)
 Helper function for light claculation; exposed here for map editor. More...
 

Private Member Functions

maptile maptile_at_internal (const tripoint &p) const
 
maptile maptile_at_internal (const tripoint &p)
 
std::pair< tripoint, maptilemaptile_has_bounds (const tripoint &p, bool bounds_checked)
 
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors (const tripoint &p)
 
void spread_gas (field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
 
void create_hot_air (const tripoint &p, int intensity)
 
bool gas_can_spread_to (field_entry &cur, const tripoint &src, const tripoint &dst)
 
void gas_spread_to (field_entry &cur, maptile &dst, const tripoint &p)
 
int burn_body_part (player &u, field_entry &cur, body_part bp, int scale)
 
bool sees (const tripoint &F, const tripoint &T, int range, int &bresenham_slope) const
 Don't expose the slope adjust outside map functions. More...
 

Friends

class editmap
 
class visitable< map_cursor >
 

Consume items on the map

The functions here consume accessible items / item charges on the map or in vehicles around the player (whose positions is given as origin).

They return a list of copies of the consumed items (with the actually consumed charges in it). The quantity / amount parameter will be reduced by the number of items/charges removed. If all required items could be removed from the map, the quantity/amount will be 0, otherwise it will contain a positive value and the remaining items must be gathered from somewhere else.

enum  iteration_state { ITER_CONTINUE = 0 , ITER_SKIP_SUBMAP , ITER_SKIP_ZLEVEL , ITER_FINISH }
 Enum used by functors in function_over to control execution. More...
 
std::set< tripointsupport_cache_dirty
 
std::vector< submap * > grid
 The list of currently loaded submaps. More...
 
std::vector< std::vector< tripoint > > traplocs
 This vector contains an entry for each trap type, it has therefor the same size as the traplist vector. More...
 
std::vector< tripointfield_furn_locs
 Vector of tripoints containing active field-emitting furniture. More...
 
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERScaches
 Holds caches for visibility, light, transparency and vehicles. More...
 
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERSpathfinding_caches
 
std::set< tripointsubmaps_with_active_items
 Set of submaps that contain active items in absolute coordinates. More...
 
lru_cache< point, char > skew_vision_cache
 Cache of coordinate pairs recently checked for visibility. More...
 
VehicleList last_full_vehicle_list
 Vehicle list doesn't change often, but is pretty expensive. More...
 
bool last_full_vehicle_list_dirty = true
 
visibility_variables visibility_variables_cache
 
std::optional< std::pair< tripoint, int > > max_populated_zlev = std::nullopt
 
std::set< vehicle * > dirty_vehicle_list
 
int my_MAPSIZE
 
bool zlevels
 
vision_adjustment vision_transparency_cache [8] = { VISION_ADJUST_NONE }
 
tripoint abs_sub
 Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation). More...
 
std::list< itemuse_amount_square (const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_amount (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_charges (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >, basecamp *bcp=nullptr)
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 Place items from item group in the rectangle f - t. More...
 
std::vector< item * > place_items (const item_group_id &loc, int chance, point p1, point p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 
std::vector< item * > put_items_from_loc (const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
 Place items from an item group at p. More...
 
std::vector< item * > spawn_items (const tripoint &p, const std::vector< item > &new_items)
 
void spawn_items (point p, const std::vector< item > &new_items)
 
void create_anomaly (const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
 
void create_anomaly (point cp, artifact_natural_property prop, bool create_rubble=true)
 
void partial_con_set (const tripoint &p, const partial_con &con)
 
void partial_con_remove (const tripoint &p)
 
partial_conpartial_con_at (const tripoint &p)
 
void trap_set (const tripoint &p, const trap_id &type)
 
const traptr_at (const tripoint &p) const
 
bool can_see_trap_at (const tripoint &p, const Character &c) const
 See trap::can_see, which is called for the trap here. More...
 
void disarm_trap (const tripoint &p)
 
void remove_trap (const tripoint &p)
 
const std::vector< tripoint > & get_furn_field_locations () const
 
const std::vector< tripoint > & trap_locations (const trap_id &type) const
 
void create_burnproducts (const tripoint &p, const item &fuel, const units::mass &burned_mass)
 
void process_fields ()
 
void process_fields_in_submap (submap *current_submap, const tripoint &submap_pos)
 
void creature_in_field (Creature &critter)
 Apply field effects to the creature when it's on a square with fields. More...
 
void creature_on_trap (Creature &critter, bool may_avoid=true)
 Apply trap effects to the creature, similar to creature_in_field. More...
 
const fieldfield_at (const tripoint &p) const
 Get the fields that are here. More...
 
fieldfield_at (const tripoint &p)
 Gets fields that are here. More...
 
time_duration get_field_age (const tripoint &p, const field_type_id &type) const
 Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns. More...
 
int get_field_intensity (const tripoint &p, const field_type_id &type) const
 Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0. More...
 
time_duration mod_field_age (const tripoint &p, const field_type_id &type, const time_duration &offset)
 Increment/decrement age of field entry at point. More...
 
int mod_field_intensity (const tripoint &p, const field_type_id &type, int offset)
 Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
time_duration set_field_age (const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
 Set age of field entry at point. More...
 
int set_field_intensity (const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
 Set intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
bool has_field_at (const tripoint &p, bool check_bounds=true)
 
field_entryget_field (const tripoint &p, const field_type_id &type)
 Get field of specific type at point. More...
 
bool dangerous_field_at (const tripoint &p)
 
bool add_field (const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
 Add field entry at point, or set intensity if present. More...
 
void remove_field (const tripoint &p, const field_type_id &field_to_remove)
 Remove field entry at xy, ignored if the field entry is not present. More...
 
void add_splatter (const field_type_id &type, const tripoint &where, int intensity=1)
 
void add_splatter_trail (const field_type_id &type, const tripoint &from, const tripoint &to)
 
void add_splash (const field_type_id &type, const tripoint &center, int radius, int intensity)
 
void propagate_field (const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
 
void emit_field (const tripoint &pos, const emit_id &src, float mul=1.0f)
 Runs one cycle of emission src which may result in propagation of fields. More...
 
void scent_blockers (std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &scent_transfer, point min, point max)
 Build the map of scent-resistant tiles. More...
 
computercomputer_at (const tripoint &p)
 
computeradd_computer (const tripoint &p, const std::string &name, int security)
 
void add_camp (const tripoint_abs_omt &omt_pos, const std::string &name)
 
void remove_submap_camp (const tripoint &)
 
basecamp hoist_submap_camp (const tripoint &p)
 
bool point_within_camp (const tripoint &point_check) const
 
bool has_graffiti_at (const tripoint &p) const
 
const std::string & graffiti_at (const tripoint &p) const
 
void set_graffiti (const tripoint &p, const std::string &contents)
 
void delete_graffiti (const tripoint &p)
 
int climb_difficulty (const tripoint &p) const
 Checks 3x3 block centered on p for terrain to climb. More...
 
bool has_floor (const tripoint &p) const
 
bool floor_between (const tripoint &first, const tripoint &second) const
 Checks if there's a floor between the two tiles. More...
 
bool supports_above (const tripoint &p) const
 Does this tile support vehicles and furniture above it. More...
 
bool has_floor_or_support (const tripoint &p) const
 
void drop_everything (const tripoint &p)
 Handles map objects of given type (not creatures) falling down. More...
 
void drop_furniture (const tripoint &p)
 
void drop_items (const tripoint &p)
 
void drop_vehicle (const tripoint &p)
 
void drop_fields (const tripoint &p)
 
void process_falling ()
 Invoked drop_everything on cached dirty tiles. More...
 
bool is_cornerfloor (const tripoint &p) const
 
void generate (const tripoint &p, const time_point &when)
 
void place_spawns (const mongroup_id &group, int chance, point p1, point p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
 
void place_gas_pump (point p, int charges, const std::string &fuel_type)
 
void place_gas_pump (point p, int charges)
 
void place_toilet (point p, int charges=6 *4)
 
void place_vending (point p, const item_group_id &type, bool reinforced=false)
 
character_id place_npc (point p, const string_id< npc_template > &type, bool force=false)
 
void apply_faction_ownership (point p1, point p2, const faction_id &id)
 
void add_spawn (const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
 
void do_vehicle_caching (int z)
 
void build_map_cache (int zlev, bool skip_lightmap=false)
 
void build_obstacle_cache (const tripoint &start, const tripoint &end, float(&obstacle_cache)[MAPSIZE_X][MAPSIZE_Y])
 
vehicleadd_vehicle (const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vgroup_id &type, point p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, point p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
float light_transparency (const tripoint &p) const
 
lit_level light_at (const tripoint &p) const
 
float ambient_light_at (const tripoint &p) const
 
bool is_transparent (const tripoint &p) const
 Returns whether the tile at p is transparent(you can look past it). More...
 
bool pl_sees (const tripoint &t, int max_range) const
 Whether the player character (g->u) can see the given square (local map coordinates). More...
 
bool pl_line_of_sight (const tripoint &t, int max_range) const
 Uses the map cache to tell if the player could see the given square. More...
 
tripoint get_abs_sub () const
 return abs_sub More...
 
tripoint getabs (const tripoint &p) const
 Translates local (to this map) coordinates of a square to global absolute coordinates. More...
 
tripoint_abs_ms getglobal (const tripoint &p) const
 
point getabs (point p) const
 
tripoint getlocal (const tripoint &p) const
 Inverse of getabs. More...
 
tripoint getlocal (const tripoint_abs_ms &p) const
 
point getlocal (point p) const
 
virtual bool inbounds (const tripoint &p) const
 
bool inbounds (const tripoint_abs_ms &p) const
 
bool inbounds (point p) const
 
bool inbounds_z (const int z) const
 
void clip_to_bounds (tripoint &p) const
 Clips the coordinates of p to fit the map bounds. More...
 
void clip_to_bounds (int &x, int &y) const
 
void clip_to_bounds (int &x, int &y, int &z) const
 
int getmapsize () const
 
bool has_zlevels () const
 
void rotate (int turns, bool setpos_safe=false)
 Rotates this map, and all of its contents, by the specified multiple of 90 degrees. More...
 
void spawn_monsters (bool ignore_sight)
 Spawn monsters from submap spawn points and from the overmap. More...
 
void rotten_item_spawn (const item &item, const tripoint &p)
 Checks to see if the item that is rotting away generates a creature when it does. More...
 
void build_outside_cache (int zlev)
 
bool build_floor_cache (int zlev)
 
void build_floor_caches ()
 
void update_suspension_cache (const int &z)
 
bash_results bash_items (const tripoint &p, const bash_params &params)
 
bash_results bash_field (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_success (const tripoint &p, const bash_params &params)
 
bash_results bash_furn_success (const tripoint &p, const bash_params &params)
 
void process_items ()
 
const level_cacheget_cache_ref (int zlev) const
 
const pathfinding_cacheget_pathfinding_cache_ref (int zlev) const
 
void update_pathfinding_cache (int zlev) const
 
void update_visibility_cache (int zlev)
 
const visibility_variablesget_visibility_variables_cache () const
 
void update_submap_active_item_status (const tripoint &p)
 
const std::set< tripoint > & get_submaps_with_active_items () const
 
tripoint_range< tripointpoints_in_rectangle (const tripoint &from, const tripoint &to) const
 
tripoint_range< tripointpoints_in_radius (const tripoint &center, size_t radius, size_t radiusz=0) const
 
tripoint_range< tripointpoints_on_zlevel () const
 Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub). More...
 
tripoint_range< tripointpoints_on_zlevel (int z) const
 Same as above, but uses the specific z-level. More...
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius) const
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius, special_item_type type) const
 
std::list< tripointfind_furnitures_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures with matching flag in the specified radius More...
 
std::list< tripointfind_furnitures_or_vparts_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures or vehicle parts with matching flag in the specified radius More...
 
std::list< Creature * > get_creatures_in_radius (const tripoint &center, size_t radius, size_t radiusz=0)
 returns creatures in specified radius More...
 
level_cacheaccess_cache (int zlev)
 
const level_cacheaccess_cache (int zlev) const
 
bool dont_draw_lower_floor (const tripoint &p)
 
void support_dirty (const tripoint &p)
 
void spawn_monsters_submap (const tripoint &gp, bool ignore_sight)
 
void spawn_monsters_submap_group (const tripoint &gp, mongroup &group, bool ignore_sight)
 
fieldget_field (const tripoint &p)
 
submapgetsubmap (size_t grididx) const
 Get the submap pointer with given index in grid, the index must be valid! More...
 
submapget_submap_at (const tripoint &p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (point p) const
 
submapget_submap_at (const tripoint &p, point &offset_p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (point p, point &offset_p) const
 
submapget_submap_at_grid (point gridp) const
 Get submap pointer in the grid at given grid coordinates. More...
 
submapget_submap_at_grid (const tripoint &gridp) const
 
int calc_max_populated_zlev ()
 Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache. More...
 
void invalidate_max_populated_zlev (int zlev)
 Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value. More...
 
int move_cost_internal (const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
 Internal versions of public functions to avoid checking same variables multiple times. More...
 
int bash_rating_internal (int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
 
bool draw_maptile (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Internal version of the drawsq. More...
 
void draw_from_above (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Draws the tile as seen from above. More...
 
int determine_wall_corner (const tripoint &p) const
 
void apply_light_source (const tripoint &p, float luminance)
 
void add_light_source (const tripoint &p, float luminance)
 
void apply_directional_light (const tripoint &p, int direction, float luminance)
 
void apply_light_arc (const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
 
void apply_light_ray (bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
 
void add_light_from_items (const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
 
std::unique_ptr< vehicleadd_vehicle_to_map (std::unique_ptr< vehicle > veh, bool merge_wrecks)
 Takes a vehicle already created with new and attempts to place it on the map, checking for collisions. More...
 
ter_id get_roof (const tripoint &p, bool allow_air) const
 
void process_items_in_submap (submap &current_submap, const tripoint &gridp)
 
void process_items_in_vehicles (submap &current_submap)
 
void process_items_in_vehicle (vehicle &cur_veh, submap &current_submap)
 
template<typename Functor >
void function_over (const tripoint &start, const tripoint &end, Functor fun) const
 Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time. More...
 
level_cacheget_cache (int zlev) const
 
pathfinding_cacheget_pathfinding_cache (int zlev) const
 
void saven (const tripoint &grid)
 
void loadn (const tripoint &grid, bool update_vehicles)
 
void loadn (point grid, bool update_vehicles)
 
void actualize (const tripoint &grid)
 Fast forward a submap that has just been loading into this map. More...
 
void add_roofs (const tripoint &grid)
 Hacks in missing roofs. More...
 
template<typename Container >
void remove_rotten_items (Container &items, const tripoint &p, temperature_flag temperature)
 Go through the list of items, update their rotten status and remove items that have rotten away completely. More...
 
void fill_funnels (const tripoint &p, const time_point &since)
 Try to fill funnel based items here. More...
 
void grow_plant (const tripoint &p)
 Try to grow a harvestable plant to the next stage(s). More...
 
void restock_fruits (const tripoint &p, const time_duration &time_since_last_actualize)
 Try to grow fruits on static plants (not planted by the player) More...
 
void produce_sap (const tripoint &p, const time_duration &time_since_last_actualize)
 Produce sap on tapped maple trees. More...
 
void rad_scorch (const tripoint &p, const time_duration &time_since_last_actualize)
 Radiation-related plant (and fungus?) death. More...
 
void decay_cosmetic_fields (const tripoint &p, const time_duration &time_since_last_actualize)
 
void player_in_field (player &u)
 
void monster_in_field (monster &z)
 
void shift_traps (const tripoint &shift)
 As part of the map shifting, this shifts the trap locations stored in traplocs. More...
 
void copy_grid (const tripoint &to, const tripoint &from)
 
void draw_map (mapgendata &dat)
 
void draw_office_tower (mapgendata &dat)
 
void draw_lab (mapgendata &dat)
 
void draw_temple (mapgendata &dat)
 
void draw_mine (mapgendata &dat)
 
void draw_anthill (mapgendata &dat)
 
void draw_slimepit (mapgendata &dat)
 
void draw_triffid (mapgendata &dat)
 
void draw_connections (mapgendata &dat)
 
bool build_transparency_cache (int zlev)
 
bool build_vision_transparency_cache (const Character &player)
 
void build_sunlight_cache (int pzlev)
 
void generate_lightmap (int zlev)
 
void build_seen_cache (const tripoint &origin, int target_z)
 Calculates the Field Of View for the provided map from the given x, y coordinates. More...
 
void apply_character_light (Character &p)
 
void apply_vision_transparency_cache (const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
 
void restore_vision_transparency_cache (const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
 
void set_abs_sub (const tripoint &p)
 Sets abs_sub, see there. More...
 
size_t get_nonant (const tripoint &gridp) const
 Get the index of a submap pointer in the grid given by grid coordinates. More...
 
size_t get_nonant (point gridp) const
 
void setsubmap (size_t grididx, submap *smap)
 Set the submap pointer in grid at the give index. More...
 

Detailed Description

Manage and cache data about a part of the map.

Despite the name, this class isn't actually responsible for managing the map as a whole. For that function, see mapbuffer. Instead, this class loads a part of the mapbuffer into a cache, and adds certain temporary information such as lighting calculations to it.

To understand the following descriptions better, you should also read Map Management

The map coordinates always start at (0, 0) for the top-left and end at (map_width-1, map_height-1) for the bottom-right.

The actual map data is stored in submap instances. These instances are managed by mapbuffer. References to the currently active submaps are stored in map::grid: 0 1 2 3 4 5 6 7 8 In this example, the top-right submap would be at grid[2].

When the player moves between submaps, the whole map is shifted, so that if the player moves one submap to the right, (0, 0) now points to a tile one submap to the right from before

Definition at line 383 of file map.h.

Member Enumeration Documentation

◆ iteration_state

enum map::iteration_state
private

Enum used by functors in function_over to control execution.

Enumerator
ITER_CONTINUE 
ITER_SKIP_SUBMAP 
ITER_SKIP_ZLEVEL 
ITER_FINISH 

Definition at line 1933 of file map.h.

1933 {
1934 ITER_CONTINUE = 0, // Keep iterating
1935 ITER_SKIP_SUBMAP, // Skip the rest of this submap
1936 ITER_SKIP_ZLEVEL, // Skip the rest of this z-level
1937 ITER_FINISH // End iteration
1938 };
@ ITER_SKIP_ZLEVEL
Definition: map.h:1936
@ ITER_SKIP_SUBMAP
Definition: map.h:1935
@ ITER_CONTINUE
Definition: map.h:1934
@ ITER_FINISH
Definition: map.h:1937

Constructor & Destructor Documentation

◆ map() [1/2]

map::map ( int  mapsize = MAPSIZE,
bool  zlev = false 
)

Definition at line 176 of file map.cpp.

177{
178 my_MAPSIZE = mapsize;
179 zlevels = zlev;
180 if( zlevels ) {
181 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE * OVERMAP_LAYERS ), nullptr );
182 } else {
183 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE ), nullptr );
184 }
185
186 for( auto &ptr : caches ) {
187 ptr = std::make_unique<level_cache>();
188 }
189
190 for( auto &ptr : pathfinding_caches ) {
191 ptr = std::make_unique<pathfinding_cache>();
192 }
193
194 dbg( DL::Info ) << "map::map(): my_MAPSIZE: " << my_MAPSIZE << " z-levels enabled:" << zlevels;
195 traplocs.resize( trap::count() );
196}
std::vector< std::vector< tripoint > > traplocs
This vector contains an entry for each trap type, it has therefor the same size as the traplist vecto...
Definition: map.h:1965
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERS > pathfinding_caches
Definition: map.h:1975
std::vector< submap * > grid
The list of currently loaded submaps.
Definition: map.h:1958
int my_MAPSIZE
Definition: map.h:1786
bool zlevels
Definition: map.h:1787
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERS > caches
Holds caches for visibility, light, transparency and vehicles.
Definition: map.h:1973
@ Info
Information (default: enabled).
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
static constexpr int OVERMAP_LAYERS
#define dbg(x)
Definition: map.cpp:140
static size_t count()
Definition: trap.cpp:95

References caches, trap::count(), dbg, grid, Info, my_MAPSIZE, OVERMAP_LAYERS, pathfinding_caches, ptr(), traplocs, and zlevels.

Referenced by check_submap_active_item_consistency().

◆ map() [2/2]

map::map ( bool  zlev)
inlineexplicit

Definition at line 391 of file map.h.

391: map( MAPSIZE, zlev ) { }
map(int mapsize=MAPSIZE, bool zlev=false)
Definition: map.cpp:176
static constexpr int MAPSIZE

◆ ~map()

map::~map ( )
virtualdefault

Member Function Documentation

◆ access_cache() [1/2]

level_cache & map::access_cache ( int  zlev)

Definition at line 8890 of file map.cpp.

8891{
8892 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8893 return *caches[zlev + OVERMAP_DEPTH];
8894 }
8895
8896 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8897 return nullcache;
8898}
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:75
static constexpr int OVERMAP_HEIGHT
static constexpr int OVERMAP_DEPTH
static level_cache nullcache
Definition: map.cpp:144

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by get_known_connections(), game::place_player_overmap(), process_items(), scent_map::update(), and game::vertical_shift().

◆ access_cache() [2/2]

const level_cache & map::access_cache ( int  zlev) const

Definition at line 8900 of file map.cpp.

8901{
8902 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8903 return *caches[zlev + OVERMAP_DEPTH];
8904 }
8905
8906 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8907 return nullcache;
8908}

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ accessible_items()

bool map::accessible_items ( const tripoint t) const

Check whether the player can access the items located .

Certain furniture/terrain may prevent that (e.g. a locked safe).

Definition at line 6696 of file map.cpp.

6697{
6698 return !has_flag( "SEALED", t ) || has_flag( "LIQUIDCONT", t );
6699}
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2375

References has_flag().

Referenced by basecamp::form_crafting_inventory(), inventory::form_from_map(), and use_charges().

◆ actualize()

void map::actualize ( const tripoint grid)
protected

Fast forward a submap that has just been loading into this map.

This is used to rot and remove rotten items, grow plants, fill funnels etc.

Definition at line 7547 of file map.cpp.

7548{
7549 submap *const tmpsub = get_submap_at_grid( grid );
7550 if( tmpsub == nullptr ) {
7551 debugmsg( "Actualize called on null submap (%d,%d,%d)", grid.x, grid.y, grid.z );
7552 return;
7553 }
7554
7555 const time_duration time_since_last_actualize = calendar::turn - tmpsub->last_touched;
7556 const bool do_funnels = ( grid.z >= 0 );
7557
7558 // check spoiled stuff, and fill up funnels while we're at it
7559 for( int x = 0; x < SEEX; x++ ) {
7560 for( int y = 0; y < SEEY; y++ ) {
7561 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7562 const point p( x, y );
7563 const auto &furn = this->furn( pnt ).obj();
7564 if( furn.has_flag( "EMITTER" ) ) {
7565 field_furn_locs.push_back( pnt );
7566 }
7567 // plants contain a seed item which must not be removed under any circumstances
7568 if( !furn.has_flag( "DONT_REMOVE_ROTTEN" ) ) {
7570 remove_rotten_items( tmpsub->get_items( { x, y } ), pnt, temperature );
7571 }
7572
7573 const auto trap_here = tmpsub->get_trap( p );
7574 if( trap_here != tr_null ) {
7575 traplocs[trap_here.to_i()].push_back( pnt );
7576 }
7577 const ter_t &ter = tmpsub->get_ter( p ).obj();
7578 if( ter.trap != tr_null && ter.trap != tr_ledge ) {
7579 traplocs[ter.trap.to_i()].push_back( pnt );
7580 }
7581
7582 if( do_funnels ) {
7583 fill_funnels( pnt, tmpsub->last_touched );
7584 }
7585
7586 grow_plant( pnt );
7587
7588 restock_fruits( pnt, time_since_last_actualize );
7589
7590 produce_sap( pnt, time_since_last_actualize );
7591
7592 rad_scorch( pnt, time_since_last_actualize );
7593
7594 decay_cosmetic_fields( pnt, time_since_last_actualize );
7595 }
7596 }
7597
7598 // the last time we touched the submap, is right now.
7599 tmpsub->last_touched = calendar::turn;
7600}
const T & obj() const
Definition: ammo_effect.cpp:26
int to_i() const
Returns the identifier as plain int.
Definition: int_id.h:84
void rad_scorch(const tripoint &p, const time_duration &time_since_last_actualize)
Radiation-related plant (and fungus?) death.
Definition: map.cpp:7481
void fill_funnels(const tripoint &p, const time_point &since)
Try to fill funnel based items here.
Definition: map.cpp:7269
submap * get_submap_at_grid(point gridp) const
Get submap pointer in the grid at given grid coordinates.
Definition: map.h:1836
void remove_rotten_items(Container &items, const tripoint &p, temperature_flag temperature)
Go through the list of items, update their rotten status and remove items that have rotten away compl...
Definition: map.cpp:7230
std::vector< tripoint > field_furn_locs
Vector of tripoints containing active field-emitting furniture.
Definition: map.h:1969
void decay_cosmetic_fields(const tripoint &p, const time_duration &time_since_last_actualize)
Definition: map.cpp:7527
void restock_fruits(const tripoint &p, const time_duration &time_since_last_actualize)
Try to grow fruits on static plants (not planted by the player)
Definition: map.cpp:7370
ter_id ter(const tripoint &p) const
Definition: map.cpp:1563
void grow_plant(const tripoint &p)
Try to grow a harvestable plant to the next stage(s).
Definition: map.cpp:7292
void produce_sap(const tripoint &p, const time_duration &time_since_last_actualize)
Produce sap on tapped maple trees.
Definition: map.cpp:7384
furn_id furn(const tripoint &p) const
Definition: map.cpp:1413
Definition: submap.h:65
time_point last_touched
Definition: submap.h:211
trap_id get_trap(point p) const
Definition: submap.h:73
ter_id get_ter(point p) const
Definition: submap.h:99
cata::colony< item > & get_items(point p)
Definition: submap.h:140
A duration defined as a number of specific time units.
Definition: calendar.h:180
point sm_to_ms_copy(point p)
temperature_flag
Definition: enums.h:42
static constexpr int SEEX
static constexpr int SEEY
static temperature_flag temperature_flag_at_point(const map &m, const tripoint &p)
Definition: map.cpp:4728
static const trap_str_id tr_ledge("tr_ledge")
time_point turn
Definition: calendar.cpp:36
quantity< int, temperature_in_millidegree_celsius_tag > temperature
Definition: point.h:35
Definition: mapdata.h:463
trap_id tr_null
Definition: trap.cpp:276

References debugmsg, decay_cosmetic_fields(), field_furn_locs, fill_funnels(), furn(), submap::get_items(), get_submap_at_grid(), submap::get_ter(), submap::get_trap(), grid, grow_plant(), submap::last_touched, int_id< T >::obj(), produce_sap(), rad_scorch(), remove_rotten_items(), restock_fruits(), SEEX, SEEY, sm_to_ms_copy(), temperature_flag_at_point(), ter(), int_id< T >::to_i(), tr_ledge, tr_null, traplocs, and calendar::turn.

Referenced by loadn().

◆ add_camp()

void map::add_camp ( const tripoint_abs_omt omt_pos,
const std::string &  name 
)

Definition at line 5719 of file map.cpp.

5720{
5721 basecamp temp_camp = basecamp( name, omt_pos );
5722 overmap_buffer.add_camp( temp_camp );
5723 g->u.camps.insert( omt_pos );
5724 g->validate_camps();
5725}
std::string name(const tripoint &p)
Definition: map.cpp:1390
void add_camp(const basecamp &camp)
Add Basecamp to overmapbuffer.
std::unique_ptr< game > g
Definition: game.cpp:285
overmapbuffer overmap_buffer

References overmapbuffer::add_camp(), g, name(), and overmap_buffer.

Referenced by get_basecamp().

◆ add_computer()

computer * map::add_computer ( const tripoint p,
const std::string &  name,
int  security 
)

Definition at line 5621 of file mapgen.cpp.

5622{
5623 // TODO: Turn this off?
5624 ter_set( p, t_console );
5625 point l;
5626 submap *const place_on_submap = get_submap_at( p, l );
5627 place_on_submap->set_computer( l, computer( name, security ) );
5628 return place_on_submap->get_computer( l );
5629}
bool ter_set(const tripoint &p, const ter_id &new_terrain)
Definition: map.cpp:1704
submap * get_submap_at(const tripoint &p) const
Get the submap pointer containing the specified position within the reality bubble.
Definition: map.cpp:8459
void set_computer(point p, const computer &c)
Definition: submap.cpp:239
const computer * get_computer(point p) const
Definition: submap.cpp:213
ter_id t_console
Definition: mapdata.cpp:707

References submap::get_computer(), get_submap_at(), name(), submap::set_computer(), t_console, and ter_set().

Referenced by jmapgen_computer::apply(), create_lab_consoles(), mission_start::place_npc_software(), and science_room().

◆ add_corpse()

void map::add_corpse ( const tripoint p)

Definition at line 8603 of file map.cpp.

8604{
8605 item body;
8606
8607 const bool isReviveSpecial = one_in( 10 );
8608
8609 if( !isReviveSpecial ) {
8610 body = item::make_corpse();
8611 } else {
8612 body = item::make_corpse( mon_zombie );
8613 body.set_flag( "REVIVE_SPECIAL" );
8614 }
8615
8616 put_items_from_loc( item_group_id( "default_zombie_clothes" ), p );
8617 if( one_in( 3 ) ) {
8618 put_items_from_loc( item_group_id( "default_zombie_items" ), p );
8619 }
8620
8621 add_item_or_charges( p, body );
8622}
Definition: item.h:210
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:511
item & set_flag(const std::string &flag)
Idempotent filter setting an item specific flag.
Definition: item.cpp:5358
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4355
std::vector< item * > put_items_from_loc(const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
Place items from an item group at p.
Definition: mapgen.cpp:5409
static const mtype_id mon_zombie("mon_zombie")
bool one_in(int chance)
Definition: rng.cpp:65
string_id< Item_group > item_group_id
Definition: type_id.h:77

References add_item_or_charges(), item::make_corpse(), mon_zombie, one_in(), put_items_from_loc(), and item::set_flag().

Referenced by add_corpse(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), and MapExtras::mx_minefield().

◆ add_field()

bool map::add_field ( const tripoint p,
const field_type_id type_id,
int  intensity = INT_MAX,
const time_duration age = 0_turns,
bool  hit_player = true 
)

Add field entry at point, or set intensity if present.

Returns
false if the field could not be created (out of bounds), otherwise true.

Definition at line 5536 of file map.cpp.

5538{
5539 if( !inbounds( p ) ) {
5540 return false;
5541 }
5542
5543 if( !type_id ) {
5544 debugmsg( "Tried to add null field" );
5545 return false;
5546 }
5547
5548 const field_type &fd_type = *type_id;
5549 intensity = std::min( intensity, fd_type.get_max_intensity() );
5550 if( intensity <= 0 ) {
5551 return false;
5552 }
5553
5554 point l;
5555 submap *const current_submap = get_submap_at( p, l );
5556 current_submap->is_uniform = false;
5558
5559 if( current_submap->get_field( l ).add_field( type_id, intensity, age ) ) {
5560 //Only adding it to the count if it doesn't exist.
5561 if( !current_submap->field_count++ ) {
5562 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5563 p.y / SEEX ) * MAPSIZE ) ) );
5564 }
5565 }
5566
5567 if( hit_player ) {
5568 Character &player_character = get_player_character();
5569 if( g != nullptr && this == &get_map() && p == player_character.pos() ) {
5570 //Hit the player with the field if it spawned on top of them.
5571 creature_in_field( player_character );
5572 }
5573 }
5574
5575 // Dirty the transparency cache now that field processing doesn't always do it
5576 if( fd_type.dirty_transparency_cache || !fd_type.is_transparent() ) {
5579 }
5580
5581 if( fd_type.is_dangerous() ) {
5583 }
5584
5585 // Ensure blood type fields don't hang in the air
5586 if( zlevels && fd_type.accelerated_decay ) {
5587 support_dirty( p );
5588 }
5589
5590 return true;
5591}
Character & get_player_character()
Definition: character.cpp:403
const tripoint & pos() const override
Definition: character.cpp:602
bool add_field(const field_type_id &field_type_to_add, int new_intensity=1, const time_duration &new_age=0_turns)
Inserts the given field_type_id into the field list for a given tile if it does not already exist.
Definition: field.cpp:190
void set_transparency_cache_dirty(const int zlev)
Sets a dirty flag on the a given cache.
Definition: map.cpp:201
level_cache & get_cache(int zlev) const
Definition: map.h:1993
virtual bool inbounds(const tripoint &p) const
Definition: map.cpp:7903
void set_pathfinding_cache_dirty(int zlev)
Definition: map.cpp:8945
void creature_in_field(Creature &critter)
Apply field effects to the creature when it's on a square with fields.
Definition: map_field.cpp:1563
void support_dirty(const tripoint &p)
Definition: map.cpp:2349
void invalidate_max_populated_zlev(int zlev)
Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above curre...
Definition: map.cpp:9176
void set_seen_cache_dirty(const tripoint change_location)
Definition: map.cpp:208
field & get_field(point p)
Definition: submap.h:149
int field_count
Definition: submap.h:210
bool is_uniform
Definition: submap.h:204
map & get_map()
Definition: map.cpp:148
bool accelerated_decay
Definition: field_type.h:180
bool is_transparent() const
Definition: field_type.h:265
bool dirty_transparency_cache
Definition: field_type.h:162
bool is_dangerous() const
Definition: field_type.h:259
int get_max_intensity() const
Definition: field_type.h:271
std::bitset< MAPSIZE *MAPSIZE > field_cache
Definition: map.h:352
int y
Definition: point.h:137
int z
Definition: point.h:138
int x
Definition: point.h:136

References field_type::accelerated_decay, field::add_field(), creature_in_field(), debugmsg, field_type::dirty_transparency_cache, level_cache::field_cache, submap::field_count, g, get_cache(), submap::get_field(), get_map(), field_type::get_max_intensity(), get_player_character(), get_submap_at(), inbounds(), invalidate_max_populated_zlev(), field_type::is_dangerous(), field_type::is_transparent(), submap::is_uniform, MAPSIZE, Character::pos(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by jmapgen_field::apply(), start_location::burn(), create_anomaly(), create_hot_air(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), drop_fields(), gas_spread_to(), hit_with_fire(), madd_field(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_spider(), game::process_artifact(), process_fields_in_submap(), set_field_intensity(), and shoot().

◆ add_item() [1/2]

item & map::add_item ( const tripoint p,
item  new_item 
)

Place an item on the map, despite the parameter name, this is not necessarily a new item.

WARNING: does -not- check volume or stack charges. player functions (drop etc) should use map::add_item_or_charges

Returns
The item that got added, or nulitem.

Definition at line 4455 of file map.cpp.

4456{
4457 if( !inbounds( p ) ) {
4458 return null_item_reference();
4459 }
4460 point l;
4461 submap *const current_submap = get_submap_at( p, l );
4462
4463 // Process foods when they are added to the map, here instead of add_item_at()
4464 // to avoid double processing food and corpses during active item processing.
4465 if( new_item.is_food() ) {
4466 new_item.process( nullptr, p, false );
4467 }
4468
4469 if( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) {
4470 return null_item_reference();
4471 }
4472
4473 if( has_flag( "DESTROY_ITEM", p ) ) {
4474 return null_item_reference();
4475 }
4476
4477 if( new_item.has_flag( "ACT_IN_FIRE" ) && get_field( p, fd_fire ) != nullptr ) {
4478 if( new_item.has_flag( "BOMB" ) && new_item.is_transformable() ) {
4479 //Convert a bomb item into its transformable version, e.g. incendiary grenade -> active incendiary grenade
4480 new_item.convert( dynamic_cast<const iuse_transform *>
4481 ( new_item.type->get_use( "transform" )->get_actor_ptr() )->target );
4482 }
4483 new_item.active = true;
4484 }
4485
4486 if( new_item.is_map() && !new_item.has_var( "reveal_map_center_omt" ) ) {
4487 new_item.set_var( "reveal_map_center_omt", ms_to_omt_copy( getabs( p ) ) );
4488 }
4489
4490 current_submap->is_uniform = false;
4492
4493 current_submap->update_lum_add( l, new_item );
4494
4495 const map_stack::iterator new_pos = current_submap->get_items( l ).insert( new_item );
4496 if( new_item.needs_processing() ) {
4497 if( current_submap->active_items.empty() ) {
4498 submaps_with_active_items.insert( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4499 }
4500 current_submap->active_items.add( *new_pos, l );
4501 }
4502
4503 return *new_pos;
4504}
void add(item &it, point location)
Adds the reference to the cache.
bool empty() const
Returns true if the cache is empty.
bool is_transformable() const
Definition: item.cpp:6989
bool process(player *carrier, const tripoint &pos, bool activate, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9621
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8952
bool active
Definition: item.h:2247
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6439
item & convert(const itype_id &new_type)
Filter converting this instance to another type preserving all other aspects.
Definition: item.cpp:537
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1079
void set_var(const std::string &name, int value)
Definition: item.cpp:1004
bool has_flag(const std::string &flag) const
Definition: item.cpp:5329
bool is_map() const
Definition: item.cpp:6740
bool is_food() const
Definition: item.cpp:6618
const itype * type
Definition: item.h:2170
Transform an item into a specific type.
Definition: iuse_actor.h:52
itype_id target
type of the resulting item
Definition: iuse_actor.h:58
std::set< tripoint > submaps_with_active_items
Set of submaps that contain active items in absolute coordinates.
Definition: map.h:1979
field_entry * get_field(const tripoint &p, const field_type_id &type)
Get field of specific type at point.
Definition: map.cpp:5513
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8407
tripoint abs_sub
Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapb...
Definition: map.h:1801
void update_lum_add(point p, const item &i)
Definition: submap.h:130
active_item_cache active_items
Definition: submap.h:208
point ms_to_omt_copy(point p)
@ LIQUID
Definition: enums.h:175
field_type_id fd_fire
Definition: field_type.cpp:345
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:326
const use_function * get_use(const std::string &iuse_name) const
Definition: itype.cpp:166
iuse_actor * get_actor_ptr()
Definition: iuse.h:316

References abs_sub, item::active, submap::active_items, active_item_cache::add(), item::convert(), active_item_cache::empty(), fd_fire, use_function::get_actor_ptr(), get_field(), submap::get_items(), get_submap_at(), itype::get_use(), getabs(), item::has_flag(), has_flag(), item::has_var(), inbounds(), invalidate_max_populated_zlev(), item::is_food(), item::is_map(), item::is_transformable(), submap::is_uniform, LIQUID, item::made_of(), ms_to_omt_copy(), item::needs_processing(), null_item_reference(), item::process(), SEEX, SEEY, item::set_var(), submaps_with_active_items, iuse_transform::target, item::type, submap::update_lum_add(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_item(), add_item_or_charges(), item::ammo_consume(), draw_mine(), extract_or_wreck_cbms(), place_gas_pump(), place_toilet(), and Character::uninstall_bionic().

◆ add_item() [2/2]

void map::add_item ( point  p,
item  new_item 
)
inline

Definition at line 1248 of file map.h.

1248 {
1249 add_item( tripoint( p, abs_sub.z ), new_item );
1250 }
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4455

References abs_sub, add_item(), and tripoint::z.

◆ add_item_or_charges() [1/2]

item & map::add_item_or_charges ( const tripoint pos,
item  obj,
bool  overflow = true 
)

Adds an item to map tile or stacks charges.

Parameters
posWhere to add item
objItem to add
overflowif destination is full attempt to drop on adjacent tiles
Returns
reference to dropped (and possibly stacked) item or null item on failure
Warning
function is relatively expensive and meant for user initiated actions, not mapgen

Definition at line 4355 of file map.cpp.

4356{
4357 // Checks if item would not be destroyed if added to this tile
4358 auto valid_tile = [&]( const tripoint & e ) {
4359 if( !inbounds( e ) ) {
4360 // should never happen
4361 debugmsg( "add_item_or_charges: %s is out of bounds (adding item '%s' [%d])",
4362 e.to_string(), obj.typeId().c_str(), obj.charges );
4363 return false;
4364 }
4365
4366 // Some tiles destroy items (e.g. lava)
4367 if( has_flag( "DESTROY_ITEM", e ) ) {
4368 return false;
4369 }
4370
4371 // Cannot drop liquids into tiles that are comprised of liquid
4372 if( obj.made_of( LIQUID ) && has_flag( "SWIMMABLE", e ) ) {
4373 return false;
4374 }
4375
4376 return true;
4377 };
4378
4379 // Checks if sufficient space at tile to add item
4380 auto valid_limits = [&]( const tripoint & e ) {
4381 return obj.volume() <= free_volume( e ) && i_at( e ).size() < MAX_ITEM_IN_SQUARE;
4382 };
4383
4384 // Performs the actual insertion of the object onto the map
4385 auto place_item = [&]( const tripoint & tile ) -> item& {
4386 if( obj.count_by_charges() )
4387 {
4388 for( auto &e : i_at( tile ) ) {
4389 if( e.merge_charges( obj ) ) {
4390 return e;
4391 }
4392 }
4393 }
4394
4395 support_dirty( tile );
4396 return add_item( tile, obj );
4397 };
4398
4399 // Some items never exist on map as a discrete item (must be contained by another item)
4400 if( obj.has_flag( "NO_DROP" ) ) {
4401 return null_item_reference();
4402 }
4403
4404 // If intended drop tile destroys the item then we don't attempt to overflow
4405 if( !valid_tile( pos ) ) {
4406 return null_item_reference();
4407 }
4408
4409 if( ( !has_flag( "NOITEM", pos ) || ( has_flag( "LIQUIDCONT", pos ) && obj.made_of( LIQUID ) ) )
4410 && valid_limits( pos ) ) {
4411 // Pass map into on_drop, because this map may not be the global map object (in mapgen, for instance).
4412 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4413 if( obj.on_drop( pos, *this ) ) {
4414 return null_item_reference();
4415 }
4416
4417 }
4418 // If tile can contain items place here...
4419 return place_item( pos );
4420
4421 } else if( overflow ) {
4422 // ...otherwise try to overflow to adjacent tiles (if permitted)
4423 const int max_dist = 2;
4424 std::vector<tripoint> tiles = closest_points_first( pos, max_dist );
4425 tiles.erase( tiles.begin() ); // we already tried this position
4426 const int max_path_length = 4 * max_dist;
4427 const pathfinding_settings setting( 0, max_dist, max_path_length, 0, false, true, false, false,
4428 false );
4429 for( const tripoint &e : tiles ) {
4430 if( !inbounds( e ) ) {
4431 continue;
4432 }
4433 //must be a path to the target tile
4434 if( route( pos, e, setting ).empty() ) {
4435 continue;
4436 }
4437 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4438 if( obj.on_drop( e, *this ) ) {
4439 return null_item_reference();
4440 }
4441 }
4442
4443 if( !valid_tile( e ) || !valid_limits( e ) ||
4444 has_flag( "NOITEM", e ) || has_flag( "SEALED", e ) ) {
4445 continue;
4446 }
4447 return place_item( e );
4448 }
4449 }
4450
4451 // failed due to lack of space at target tile (+/- overflow tiles)
4452 return null_item_reference();
4453}
size_t size() const
Definition: item_stack.cpp:10
bool count_by_charges() const
Definition: item.cpp:6031
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:5130
int charges
Definition: item.h:2209
bool on_drop(const tripoint &pos)
Invokes item type's itype::drop_action.
Definition: item.cpp:10017
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8375
map_stack i_at(const tripoint &p)
Definition: map.cpp:4210
units::volume free_volume(const tripoint &p)
Definition: map.cpp:4350
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:255
std::vector< coords::coord_point< Point, Origin, Scale > > closest_points_first(const coords::coord_point< Point, Origin, Scale > &loc, int min_dist, int max_dist)
Definition: coordinates.h:596
static constexpr int MAX_ITEM_IN_SQUARE

References add_item(), string_id< T >::c_str(), item::charges, closest_points_first(), item::count_by_charges(), debugmsg, free_volume(), item::has_flag(), has_flag(), i_at(), inbounds(), LIQUID, item::made_of(), MAX_ITEM_IN_SQUARE, null_item_reference(), item::on_drop(), wrapped_vehicle::pos, route(), item_stack::size(), support_dirty(), item::typeId(), and item::volume().

Referenced by add_corpse(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), jmapgen_liquid_item::apply(), defense_game::caravan(), game::catch_a_monster(), doors::close_door(), game::disable_robot(), draw_lab(), Character::drop_invalid_inventory(), drop_items(), talk_function::drop_weapon(), farm_action(), talk_function::field_plant(), game::forced_door_closing(), handle_harvest(), pickup::handle_spillable_contents(), map_stack::insert(), make_mon_corpse(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), om_set_hide_site(), Character::place_corpse(), basecamp::place_results(), talk_function::player_weapon_drop(), process_fields_in_submap(), monexamine::remove_armor(), monexamine::remove_bag_from(), monexamine::remove_battery(), set_item_map(), smash_items(), spawn_an_item(), spawn_artifact(), spawn_items(), spawn_natural_artifact(), item::spill_contents(), and item_contents::spill_contents().

◆ add_item_or_charges() [2/2]

item & map::add_item_or_charges ( point  p,
item  obj,
bool  overflow = true 
)
inline

Definition at line 1236 of file map.h.

1236 {
1237 return add_item_or_charges( tripoint( p, abs_sub.z ), obj, overflow );
1238 }

References abs_sub, add_item_or_charges(), and tripoint::z.

◆ add_light_from_items()

void map::add_light_from_items ( const tripoint p,
item_stack::iterator  begin,
item_stack::iterator  end 
)
private

Definition at line 87 of file lightmap.cpp.

89{
90 for( auto itm_it = begin; itm_it != end; ++itm_it ) {
91 float ilum = 0.0f; // brightness
92 units::angle iwidth = 0_degrees; // 0-360 degrees. 0 is a circular light_source
93 units::angle idir = 0_degrees; // otherwise, it's a light_arc pointed in this direction
94 if( itm_it->getlight( ilum, iwidth, idir ) ) {
95 if( iwidth > 0_degrees ) {
96 apply_light_arc( p, idir, ilum, iwidth );
97 } else {
98 add_light_source( p, ilum );
99 }
100 }
101 }
102}
void apply_light_arc(const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
Definition: lightmap.cpp:1871
void add_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:649

References add_light_source(), and apply_light_arc().

Referenced by generate_lightmap().

◆ add_light_source()

void map::add_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 649 of file lightmap.cpp.

650{
651 auto &light_source_buffer = get_cache( p.z ).light_source_buffer;
652 light_source_buffer[p.x][p.y] = std::max( luminance, light_source_buffer[p.x][p.y] );
653}
float light_source_buffer[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:318

References get_cache(), level_cache::light_source_buffer, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_light_from_items(), and generate_lightmap().

◆ add_roofs()

void map::add_roofs ( const tripoint grid)
protected

Hacks in missing roofs.

Should be removed when 3D mapgen is done.

Definition at line 7602 of file map.cpp.

7603{
7604 if( !zlevels ) {
7605 // No roofs required!
7606 // Why not? Because submaps below and above don't exist yet
7607 return;
7608 }
7609
7610 submap *const sub_here = get_submap_at_grid( grid );
7611 if( sub_here == nullptr ) {
7612 debugmsg( "Tried to add roofs/floors on null submap on %d,%d,%d",
7613 grid.x, grid.y, grid.z );
7614 return;
7615 }
7616
7617 bool check_roof = grid.z > -OVERMAP_DEPTH;
7618
7619 submap *const sub_below = check_roof ? get_submap_at_grid( grid + tripoint_below ) : nullptr;
7620
7621 if( check_roof && sub_below == nullptr ) {
7622 debugmsg( "Tried to add roofs to sm at %d,%d,%d, but sm below doesn't exist",
7623 grid.x, grid.y, grid.z );
7624 return;
7625 }
7626
7627 for( int x = 0; x < SEEX; x++ ) {
7628 for( int y = 0; y < SEEY; y++ ) {
7629 const ter_id ter_here = sub_here->get_ter( { x, y } );
7630 if( ter_here != t_open_air ) {
7631 continue;
7632 }
7633
7634 if( !check_roof ) {
7635 // Make sure we don't have open air at lowest z-level
7636 sub_here->set_ter( { x, y }, t_rock_floor );
7637 continue;
7638 }
7639
7640 const ter_t &ter_below = sub_below->get_ter( { x, y } ).obj();
7641 if( ter_below.roof ) {
7642 // TODO: Make roof variable a ter_id to speed this up
7643 sub_here->set_ter( { x, y }, ter_below.roof.id() );
7644 }
7645 }
7646 }
7647}
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54
void set_ter(point p, ter_id terr)
Definition: submap.h:103
ter_id t_open_air
Definition: mapdata.cpp:730
ter_id t_rock_floor
Definition: mapdata.cpp:630
static constexpr tripoint tripoint_below
Definition: point.h:281
ter_str_id roof
Definition: mapdata.h:473

References debugmsg, get_submap_at_grid(), submap::get_ter(), grid, string_id< T >::id(), OVERMAP_DEPTH, ter_t::roof, SEEX, SEEY, submap::set_ter(), t_open_air, t_rock_floor, tripoint_below, and zlevels.

Referenced by loadn(), and shift().

◆ add_spawn()

void map::add_spawn ( const mtype_id type,
int  count,
const tripoint p,
bool  friendly = false,
int  faction_id = -1,
int  mission_id = -1,
const std::string &  name = "NONE" 
) const

Definition at line 5416 of file mapgen.cpp.

5418{
5419 if( p.x < 0 || p.x >= SEEX * my_MAPSIZE || p.y < 0 || p.y >= SEEY * my_MAPSIZE ) {
5420 debugmsg( "Bad add_spawn(%s, %d, %d, %d)", type.c_str(), count, p.x, p.y );
5421 return;
5422 }
5423 point offset;
5424 submap *place_on_submap = get_submap_at( p, offset );
5425
5426 if( !place_on_submap ) {
5427 debugmsg( "centadodecamonant doesn't exist in grid; within add_spawn(%s, %d, %d, %d, %d)",
5428 type.c_str(), count, p.x, p.y, p.z );
5429 return;
5430 }
5432 return;
5433 }
5434 spawn_point tmp( type, count, offset, faction_id, mission_id, friendly, name );
5435 place_on_submap->spawns.push_back( tmp );
5436}
static bool monster_is_blacklisted(const mtype_id &m)
Definition: mongroup.cpp:280
std::vector< spawn_point > spawns
Definition: submap.h:212
constexpr size_t count()
Definition: fmtlib_core.h:1073

References detail::count(), debugmsg, friendly, get_submap_at(), MonsterGroupManager::monster_is_blacklisted(), my_MAPSIZE, name(), SEEX, SEEY, submap::spawns, type, tripoint::x, tripoint::y, and tripoint::z.

Referenced by jmapgen_monster::apply(), generate(), mission_start::kill_horde_master(), mapgen_ants_larvae(), mapgen_ants_larvae_acid(), mapgen_ants_queen(), mapgen_ants_queen_acid(), mapgen_hive(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_jabberwock(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_military(), MapExtras::mx_roadblock(), MapExtras::mx_science(), MapExtras::mx_shia(), MapExtras::mx_spider(), mission_start::place_dog(), place_spawns(), mission_start::place_zombie_mom(), process_fields_in_submap(), and rotten_item_spawn().

◆ add_splash()

void map::add_splash ( const field_type_id type,
const tripoint center,
int  radius,
int  intensity 
)

Definition at line 5668 of file map.cpp.

5670{
5671 if( !type.id() ) {
5672 return;
5673 }
5674 // TODO: use Bresenham here and take obstacles into account
5675 for( const tripoint &pnt : points_in_radius( center, radius ) ) {
5676 if( trig_dist( pnt, center ) <= radius && !one_in( intensity ) ) {
5677 add_splatter( type, pnt );
5678 }
5679 }
5680}
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:8762
void add_splatter(const field_type_id &type, const tripoint &where, int intensity=1)
Definition: map.cpp:5619
int trig_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:512

References add_splatter(), center, one_in(), points_in_radius(), trig_dist(), and type.

Referenced by smash_items().

◆ add_splatter()

void map::add_splatter ( const field_type_id type,
const tripoint where,
int  intensity = 1 
)

Definition at line 5619 of file map.cpp.

5620{
5621 if( !type.id() || intensity <= 0 ) {
5622 return;
5623 }
5624 if( type.obj().is_splattering ) {
5625 if( const optional_vpart_position vp = veh_at( where ) ) {
5626 vehicle *const veh = &vp->vehicle();
5627 // Might be -1 if all the vehicle's parts at where are marked for removal
5628 const int part = veh->part_displayed_at( vp->mount() );
5629 if( part != -1 ) {
5630 veh->part( part ).blood += 200 * std::min( intensity, 3 ) / 3;
5631 return;
5632 }
5633 }
5634 }
5635 mod_field_intensity( where, type, intensity );
5636}
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1074
int mod_field_intensity(const tripoint &p, const field_type_id &type, int offset)
Increment/decrement intensity of field entry at point, creating if not present, removing if intensity...
Definition: map.cpp:5455
Simple wrapper to forward functions that may return a std::optional to vpart_position.
A vehicle as a whole with all its components.
Definition: vehicle.h:383
int part_displayed_at(point dp) const
Returns which part (as an index into the parts list) is the one that will be displayed for the given ...
Definition: vehicle.cpp:2972
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:253
vehicle_part & part(int part_num)
Definition: vehicle.cpp:7105
int blood
how much blood covers part (in turns).
Definition: vehicle_part.h:237

References vehicle_part::blood, mod_field_intensity(), vehicle::part(), vehicle::part_displayed_at(), type, veh_at(), and vehicle::vehicle().

Referenced by add_splash(), add_splatter_trail(), and Creature::bleed().

◆ add_splatter_trail()

void map::add_splatter_trail ( const field_type_id type,
const tripoint from,
const tripoint to 
)

Definition at line 5638 of file map.cpp.

5640{
5641 if( !type.id() ) {
5642 return;
5643 }
5644 auto trail = line_to( from, to );
5645 int remainder = trail.size();
5646 tripoint last_point = from;
5647 for( tripoint &elem : trail ) {
5648 add_splatter( type, elem );
5649 remainder--;
5650 if( obstructed_by_vehicle_rotation( last_point, elem ) ) {
5651 if( one_in( 2 ) ) {
5652 elem.x = last_point.x;
5653 add_splatter( type, elem, remainder );
5654 } else {
5655 elem.y = last_point.y;
5656 add_splatter( type, elem, remainder );
5657 }
5658 return;
5659 }
5660 if( impassable( elem ) ) { // Blood splatters stop at walls.
5661 add_splatter( type, elem, remainder );
5662 return;
5663 }
5664 last_point = elem;
5665 }
5666}
bool obstructed_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.
Definition: map.cpp:6623
bool impassable(const tripoint &p) const
Definition: map.cpp:1860
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548

References add_splatter(), impassable(), line_to(), obstructed_by_vehicle_rotation(), one_in(), type, tripoint::x, and tripoint::y.

Referenced by MapExtras::mx_casings(), MapExtras::mx_mayhem(), and MapExtras::mx_minefield().

◆ add_vehicle() [1/4]

vehicle * map::add_vehicle ( const vgroup_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

◆ add_vehicle() [2/4]

vehicle * map::add_vehicle ( const vgroup_id type,
point  p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5444 of file mapgen.cpp.

5446{
5447 return add_vehicle( type.obj().pick(), p, dir, veh_fuel, veh_status, merge_wrecks );
5448}

References add_vehicle(), and type.

◆ add_vehicle() [3/4]

vehicle * map::add_vehicle ( const vproto_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5456 of file mapgen.cpp.

5458{
5459 if( !type.is_valid() ) {
5460 debugmsg( "Nonexistent vehicle type: \"%s\"", type.c_str() );
5461 return nullptr;
5462 }
5463 if( !inbounds( p ) ) {
5464 dbg( DL::Warn ) << string_format( "Out of bounds add_vehicle t=%s d=%d p=%s",
5465 type, to_degrees( dir ), p.to_string() );
5466 return nullptr;
5467 }
5468
5469 // debugmsg("n=%d x=%d y=%d MAPSIZE=%d ^2=%d", nonant, x, y, MAPSIZE, MAPSIZE*MAPSIZE);
5470 auto veh = std::make_unique<vehicle>( type, veh_fuel, veh_status );
5471 tripoint p_ms = p;
5472 veh->sm_pos = ms_to_sm_remain( p_ms );
5473 veh->pos = p_ms.xy();
5474 veh->place_spawn_items();
5475 // for backwards compatibility, we always spawn with a pivot point of (0,0) so
5476 // that the mount at (0,0) is located at the spawn position.
5477 veh->set_facing_and_pivot( dir, point_zero, false );
5478 //debugmsg("adding veh: %d, sm: %d,%d,%d, pos: %d, %d", veh, veh->smx, veh->smy, veh->smz, veh->posx, veh->posy);
5479 std::unique_ptr<vehicle> placed_vehicle_up =
5480 add_vehicle_to_map( std::move( veh ), merge_wrecks );
5481 vehicle *placed_vehicle = placed_vehicle_up.get();
5482
5483 if( placed_vehicle != nullptr ) {
5484 submap *place_on_submap = get_submap_at_grid( placed_vehicle->sm_pos );
5485 place_on_submap->vehicles.push_back( std::move( placed_vehicle_up ) );
5486 place_on_submap->is_uniform = false;
5488
5489 auto &ch = get_cache( placed_vehicle->sm_pos.z );
5490 ch.vehicle_list.insert( placed_vehicle );
5491 add_vehicle_to_cache( placed_vehicle );
5492
5493 //debugmsg ("grid[%d]->vehicles.size=%d veh.parts.size=%d", nonant, grid[nonant]->vehicles.size(),veh.parts.size());
5494 }
5495 return placed_vehicle;
5496}
std::unique_ptr< vehicle > add_vehicle_to_map(std::unique_ptr< vehicle > veh, bool merge_wrecks)
Takes a vehicle already created with new and attempts to place it on the map, checking for collisions...
Definition: mapgen.cpp:5507
void add_vehicle_to_cache(vehicle *)
Definition: map.cpp:331
std::vector< std::unique_ptr< vehicle > > vehicles
Vehicles on this submap (their (0,0) point is on this submap).
Definition: submap.h:218
tripoint sm_pos
Submap coordinates of the currently loaded submap (see game::m) that contains this vehicle.
Definition: vehicle.h:1633
point ms_to_sm_remain(int &x, int &y)
@ Warn
Warning (default: enabled).
#define dbg(x)
Definition: mapgen.cpp:101
bool move(avatar &you, map &m, const tripoint &d)
constexpr double to_degrees(const units::angle v)
Definition: units_angle.h:36
static constexpr point point_zero
Definition: point.h:260
std::string string_format(std::string_view format, Args &&...args)
Simple wrapper over string_formatter::parse.
constexpr point xy() const
Definition: point.h:206
std::string to_string() const
Definition: point.cpp:34

References add_vehicle_to_cache(), add_vehicle_to_map(), dbg, debugmsg, get_cache(), get_submap_at_grid(), inbounds(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), ms_to_sm_remain(), point_zero, vehicle::sm_pos, string_format(), units::to_degrees(), tripoint::to_string(), type, submap::vehicles, Warn, tripoint::xy(), and tripoint::z.

◆ add_vehicle() [4/4]

vehicle * map::add_vehicle ( const vproto_id type,
point  p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5450 of file mapgen.cpp.

5452{
5453 return add_vehicle( type, tripoint( p, abs_sub.z ), dir, veh_fuel, veh_status, merge_wrecks );
5454}

References abs_sub, add_vehicle(), type, and tripoint::z.

◆ add_vehicle_to_cache()

void map::add_vehicle_to_cache ( vehicle veh)

Definition at line 331 of file map.cpp.

332{
333 if( veh == nullptr ) {
334 debugmsg( "Tried to add null vehicle to cache" );
335 return;
336 }
337
338 // Get parts
339 for( const vpart_reference &vpr : veh->get_all_parts() ) {
340 if( vpr.part().removed ) {
341 continue;
342 }
343 const tripoint p = veh->global_part_pos3( vpr.part() );
344 level_cache &ch = get_cache( p.z );
345 ch.veh_in_active_range = true;
346 ch.veh_cached_parts[p] = std::make_pair( veh, static_cast<int>( vpr.part_index() ) );
347 if( inbounds( p ) ) {
348 ch.veh_exists_at[p.x][p.y] = true;
349 }
350 }
351
353}
bool last_full_vehicle_list_dirty
Definition: map.h:1990
vehicle_part_range get_all_parts() const
Yields a range containing all parts (including broken ones) that can be iterated over.
Definition: vehicle.cpp:7095
tripoint global_part_pos3(const int &index) const
Get the coordinates of the studied part of the vehicle.
Definition: vehicle.cpp:3288
This is a wrapper over a vehicle pointer and a reference to a part of it.
bool veh_in_active_range
Definition: map.h:354
bool veh_exists_at[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:355
std::map< tripoint, std::pair< vehicle *, int > > veh_cached_parts
Definition: map.h:356

References debugmsg, vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), last_full_vehicle_list_dirty, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_vehicle(), displace_vehicle(), construct::done_vehicle(), loadn(), and reset_vehicle_cache().

◆ add_vehicle_to_map()

std::unique_ptr< vehicle > map::add_vehicle_to_map ( std::unique_ptr< vehicle veh,
bool  merge_wrecks 
)
private

Takes a vehicle already created with new and attempts to place it on the map, checking for collisions.

If the vehicle can't be placed, returns NULL, otherwise returns a pointer to the placed vehicle, which may not necessarily be the one passed in (if wreckage is created by fusing cars).

Parameters
vehThe vehicle to place on the map.
merge_wrecksWhether crashed vehicles become part of each other
Returns
The vehicle that was finally placed.

Definition at line 5507 of file mapgen.cpp.

5509{
5510 //We only want to check once per square, so loop over all structural parts
5511 std::vector<int> frame_indices = veh->all_parts_at_location( "structure" );
5512
5513 //Check for boat type vehicles that should be placeable in deep water
5514 const bool can_float = size( veh->get_avail_parts( "FLOATS" ) ) > 2;
5515
5516 //When hitting a wall, only smash the vehicle once (but walls many times)
5517 bool needs_smashing = false;
5518
5519 veh->attach();
5520 veh->refresh_position();
5521
5522 for( std::vector<int>::const_iterator part = frame_indices.begin();
5523 part != frame_indices.end(); part++ ) {
5524 const auto p = veh->global_part_pos3( *part );
5525
5526 //Don't spawn anything in water
5527 if( has_flag_ter( TFLAG_DEEP_WATER, p ) && !can_float ) {
5528 return nullptr;
5529 }
5530
5531 // Don't spawn shopping carts on top of another vehicle or other obstacle.
5532 if( veh->type == vproto_id( "shopping_cart" ) ) {
5533 if( veh_at( p ) || impassable( p ) ) {
5534 return nullptr;
5535 }
5536 }
5537
5538 //For other vehicles, simulate collisions with (non-shopping cart) stuff
5539 vehicle *const other_veh = veh_pointer_or_null( veh_at( p ) );
5540 if( other_veh != nullptr && other_veh->type != vproto_id( "shopping_cart" ) ) {
5541 if( !merge_wrecks ) {
5542 return nullptr;
5543 }
5544
5545 // Hard wreck-merging limit: 200 tiles
5546 // Merging is slow for big vehicles which lags the mapgen
5547 if( frame_indices.size() + other_veh->all_parts_at_location( "structure" ).size() > 200 ) {
5548 return nullptr;
5549 }
5550
5551 /* There's a vehicle here, so let's fuse them together into wreckage and
5552 * smash them up. It'll look like a nasty collision has occurred.
5553 * Trying to do a local->global->local conversion would be a major
5554 * headache, so instead, let's make another vehicle whose (0, 0) point
5555 * is the (0, 0) of the existing vehicle, convert the coordinates of both
5556 * vehicles into global coordinates, find the distance between them and
5557 * p and then install them that way.
5558 * Create a vehicle with type "null" so it starts out empty. */
5559 auto wreckage = std::make_unique<vehicle>();
5560 wreckage->pos = other_veh->pos;
5561 wreckage->sm_pos = other_veh->sm_pos;
5562
5563 //Where are we on the global scale?
5564 const tripoint global_pos = wreckage->global_pos3();
5565
5566 for( const vpart_reference &vpr : veh->get_all_parts() ) {
5567 const tripoint part_pos = veh->global_part_pos3( vpr.part() ) - global_pos;
5568 // TODO: change mount points to be tripoint
5569 wreckage->install_part( part_pos.xy(), vpr.part() );
5570 }
5571
5572 for( const vpart_reference &vpr : other_veh->get_all_parts() ) {
5573 const tripoint part_pos = other_veh->global_part_pos3( vpr.part() ) - global_pos;
5574 wreckage->install_part( part_pos.xy(), vpr.part() );
5575
5576 }
5577
5578 wreckage->name = _( "Wreckage" );
5579
5580 // Now get rid of the old vehicles
5581 std::unique_ptr<vehicle> old_veh = detach_vehicle( other_veh );
5582 // Failure has happened here when caches are corrupted due to bugs.
5583 // Add an assertion to avoid null-pointer dereference later.
5584 assert( old_veh );
5585
5586 // Try again with the wreckage
5587 std::unique_ptr<vehicle> new_veh = add_vehicle_to_map( std::move( wreckage ), true );
5588 if( new_veh != nullptr ) {
5589 new_veh->smash( *this );
5590 return new_veh;
5591 }
5592
5593 // If adding the wreck failed, we want to restore the vehicle we tried to merge with
5594 add_vehicle_to_map( std::move( old_veh ), false );
5595 return nullptr;
5596
5597 } else if( impassable( p ) ) {
5598 if( !merge_wrecks ) {
5599 return nullptr;
5600 }
5601
5602 // There's a wall or other obstacle here; destroy it
5603 destroy( p, true );
5604
5605 // Some weird terrain, don't place the vehicle
5606 if( impassable( p ) ) {
5607 return nullptr;
5608 }
5609
5610 needs_smashing = true;
5611 }
5612 }
5613
5614 if( needs_smashing ) {
5615 veh->smash( *this );
5616 }
5617
5618 return veh;
5619}
void destroy(const tripoint &p, bool silent=false)
Keeps bashing a square until it can't be bashed anymore.
Definition: map.cpp:3735
std::unique_ptr< vehicle > detach_vehicle(vehicle *veh)
Definition: map.cpp:414
bool has_flag_ter(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2394
point pos
Position of the vehicle inside the submap that contains the vehicle.
Definition: vehicle.h:1648
vproto_id type
Type of the vehicle as it was spawned.
Definition: vehicle.h:1587
std::vector< int > all_parts_at_location(const std::string &location) const
Returns all parts in the vehicle that exist in the given location slot.
Definition: vehicle.cpp:2783
@ TFLAG_DEEP_WATER
Definition: mapdata.h:302
const size_t size
Definition: om_direction.h:28
#define _(msg)
Definition: translations.h:116
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, add_vehicle_to_map(), vehicle::all_parts_at_location(), destroy(), detach_vehicle(), vehicle::get_all_parts(), vehicle::global_part_pos3(), has_flag_ter(), impassable(), avatar_action::move(), vehicle::pos, om_direction::size, vehicle::sm_pos, TFLAG_DEEP_WATER, vehicle::type, veh_at(), veh_pointer_or_null(), and tripoint::xy().

Referenced by add_vehicle(), and add_vehicle_to_map().

◆ adjust_radiation() [1/2]

void map::adjust_radiation ( const tripoint p,
int  delta 
)

Increment the radiation in the given tile by the given delta (decrement it if delta is negative)

Definition at line 4178 of file map.cpp.

4179{
4180 if( !inbounds( p ) ) {
4181 return;
4182 }
4183
4184 point l;
4185 submap *const current_submap = get_submap_at( p, l );
4186
4187 int current_radiation = current_submap->get_radiation( l );
4188 current_submap->set_radiation( l, current_radiation + delta );
4189}
void set_radiation(point p, const int radiation)
Definition: submap.h:116
int get_radiation(point p) const
Definition: submap.h:112

References submap::get_radiation(), get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by adjust_radiation(), MapExtras::mx_crater(), MapExtras::mx_portal_in(), and process_fields_in_submap().

◆ adjust_radiation() [2/2]

void map::adjust_radiation ( point  p,
const int  delta 
)
inline

Definition at line 1164 of file map.h.

1164 {
1165 adjust_radiation( tripoint( p, abs_sub.z ), delta );
1166 }
void adjust_radiation(const tripoint &p, int delta)
Increment the radiation in the given tile by the given delta (decrement it if delta is negative)
Definition: map.cpp:4178

References abs_sub, adjust_radiation(), and tripoint::z.

◆ ambient_light_at()

float map::ambient_light_at ( const tripoint p) const

Definition at line 682 of file lightmap.cpp.

683{
684 if( !inbounds( p ) ) {
685 return 0.0f;
686 }
687
688 return get_cache_ref( p.z ).lm[p.x][p.y].max();
689}
const level_cache & get_cache_ref(int zlev) const
Definition: map.h:2006
float max() const
Definition: shadowcasting.h:45
four_quadrants lm[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:314

References get_cache_ref(), inbounds(), level_cache::lm, four_quadrants::max(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_character_light(), and game::print_terrain_info().

◆ apparent_light_at()

lit_level map::apparent_light_at ( const tripoint p,
const visibility_variables cache 
) const

Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc.

Parameters
pThe tile on this map to draw.
cacheCurrently cached visibility parameters

Definition at line 765 of file lightmap.cpp.

766{
767 const int dist = rl_dist( g->u.pos(), p );
768
769 // Clairvoyance overrides everything.
770 if( dist <= cache.u_clairvoyance ) {
771 return lit_level::BRIGHT;
772 }
773 const auto &map_cache = get_cache_ref( p.z );
774 const apparent_light_info a = apparent_light_helper( map_cache, p );
775
776 // Unimpaired range is an override to strictly limit vision range based on various conditions,
777 // but the player can still see light sources.
778 if( dist > g->u.unimpaired_range() ) {
779 if( !a.obstructed && map_cache.sm[p.x][p.y] > 0.0 ) {
781 } else {
782 return lit_level::DARK;
783 }
784 }
785 if( a.obstructed ) {
786 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
787 if( a.apparent_light > cache.g_light_level ) {
788 // This represents too hazy to see detail,
789 // but enough light getting through to illuminate.
791 } else {
792 // If it's not brighter than the surroundings, it just ends up shadowy.
793 return lit_level::LOW;
794 }
795 } else {
796 return lit_level::BLANK;
797 }
798 }
799 // Then we just search for the light level in descending order.
800 if( a.apparent_light > LIGHT_SOURCE_BRIGHT || map_cache.sm[p.x][p.y] > 0.0 ) {
801 return lit_level::BRIGHT;
802 }
803 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
804 return lit_level::LIT;
805 }
806 if( a.apparent_light >= cache.vision_threshold ) {
807 return lit_level::LOW;
808 } else {
809 return lit_level::BLANK;
810 }
811}
static apparent_light_info apparent_light_helper(const level_cache &map_cache, const tripoint &p)
Helper function for light claculation; exposed here for map editor.
Definition: lightmap.cpp:703
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
static constexpr float LIGHT_SOURCE_BRIGHT
Definition: lightmap.h:9
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
constexpr double a
Definition: magic.cpp:1030
float vision_threshold
Definition: map.h:128
int u_clairvoyance
Definition: map.h:127

References a, apparent_light_helper(), BLANK, BRIGHT, BRIGHT_ONLY, DARK, g, visibility_variables::g_light_level, get_cache_ref(), LIGHT_AMBIENT_LIT, LIGHT_SOURCE_BRIGHT, LIT, LOW, rl_dist(), visibility_variables::u_clairvoyance, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw_look_around_cursor(), game::print_all_tile_info(), and update_visibility_cache().

◆ apparent_light_helper()

map::apparent_light_info map::apparent_light_helper ( const level_cache map_cache,
const tripoint p 
)
static

Helper function for light claculation; exposed here for map editor.

Definition at line 703 of file lightmap.cpp.

705{
706 const float vis = std::max( map_cache.seen_cache[p.x][p.y], map_cache.camera_cache[p.x][p.y] );
707 const bool obstructed = vis <= LIGHT_TRANSPARENCY_SOLID + 0.1;
708
709 auto is_opaque = [&map_cache]( point p ) {
710 return map_cache.transparency_cache[p.x][p.y] <= LIGHT_TRANSPARENCY_SOLID &&
711 get_player_character().pos().xy() != p;
712 };
713
714 const bool p_opaque = is_opaque( p.xy() );
715 float apparent_light;
716
717 if( p_opaque && vis > 0 ) {
718 // This is the complicated case. We want to check which quadrants the
719 // player can see the tile from, and only count light values from those
720 // quadrants.
721 struct offset_and_quadrants {
722 point offset;
723 std::array<quadrant, 2> quadrants;
724 };
725 static constexpr std::array<offset_and_quadrants, 8> adjacent_offsets = {{
734 }
735 };
736
737 four_quadrants seen_from( 0 );
738 for( const offset_and_quadrants &oq : adjacent_offsets ) {
739 const point neighbour = p.xy() + oq.offset;
740
741 if( !lightmap_boundaries.contains( neighbour ) ) {
742 continue;
743 }
744 if( is_opaque( neighbour ) ) {
745 continue;
746 }
747 if( map_cache.seen_cache[neighbour.x][neighbour.y] == 0 &&
748 map_cache.camera_cache[neighbour.x][neighbour.y] == 0 ) {
749 continue;
750 }
751 // This is a non-opaque visible neighbour, so count visibility from the relevant
752 // quadrants
753 seen_from[oq.quadrants[0]] = vis;
754 seen_from[oq.quadrants[1]] = vis;
755 }
756 apparent_light = ( seen_from * map_cache.lm[p.x][p.y] ).max();
757 } else {
758 // This is the simple case, for a non-opaque tile light from all
759 // directions is equivalent
760 apparent_light = vis * map_cache.lm[p.x][p.y].max();
761 }
762 return { obstructed, apparent_light };
763}
const half_open_rectangle< point > lightmap_boundaries(lightmap_boundary_min, lightmap_boundary_max)
static constexpr float LIGHT_TRANSPARENCY_SOLID
Transparency 101: Transparency usually ranges between 0.038 (open air) and 0.38 (regular smoke).
Definition: lightmap.h:32
static constexpr point point_south_west
Definition: point.h:267
static constexpr point point_west
Definition: point.h:268
static constexpr point point_north_east
Definition: point.h:263
static constexpr point point_north_west
Definition: point.h:269
static constexpr point point_south_east
Definition: point.h:265
static constexpr point point_south
Definition: point.h:266
static constexpr point point_north
Definition: point.h:262
static constexpr point point_east
Definition: point.h:264
float seen_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:343
float transparency_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:332
float camera_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:347
int y
Definition: point.h:39
int x
Definition: point.h:38

References level_cache::camera_cache, get_player_character(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, four_quadrants::max(), NE, NW, point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, point_west, Character::pos(), SE, level_cache::seen_cache, SW, level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by apparent_light_at(), pl_sees(), and editmap::update_view_with_help().

◆ apply_character_light()

void map::apply_character_light ( Character p)
protected

Definition at line 263 of file lightmap.cpp.

264{
265 if( p.has_effect( effect_onfire ) ) {
266 apply_light_source( p.pos(), 8 );
267 } else if( p.has_effect( effect_haslight ) ) {
268 apply_light_source( p.pos(), 4 );
269 }
270
271 const float held_luminance = p.active_light();
272 if( held_luminance > LIGHT_AMBIENT_LOW ) {
273 apply_light_source( p.pos(), held_luminance );
274 }
275
276 if( held_luminance >= 4 && held_luminance > ambient_light_at( p.pos() ) - 0.5f ) {
277 p.add_effect( effect_haslight, 1_turns );
278 }
279}
float active_light() const
Returns character luminosity based on the brightest active item they are carrying.
Definition: character.cpp:6310
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:1008
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1207
void apply_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:1750
float ambient_light_at(const tripoint &p) const
Definition: lightmap.cpp:682
static const efftype_id effect_haslight("haslight")
static const efftype_id effect_onfire("onfire")
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14

References Character::active_light(), Creature::add_effect(), ambient_light_at(), apply_light_source(), effect_haslight, effect_onfire, Creature::has_effect(), LIGHT_AMBIENT_LOW, and Character::pos().

Referenced by generate_lightmap().

◆ apply_directional_light()

void map::apply_directional_light ( const tripoint p,
int  direction,
float  luminance 
)
private

Definition at line 1831 of file lightmap.cpp.

1832{
1833 const point p2( p.xy() );
1834
1835 auto &cache = get_cache( p.z );
1836 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1837 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1838 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1839
1840 if( direction == 90 ) {
1843 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1846 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1847 } else if( direction == 0 ) {
1850 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1853 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1854 } else if( direction == 270 ) {
1857 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1860 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1861 } else if( direction == 180 ) {
1864 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1867 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1868 }
1869}
static constexpr int MAPSIZE_Y
static constexpr int MAPSIZE_X
static float light_from_lookup(const float &numerator, const float &transparency, const int &distance)
Definition: lightmap.cpp:1744
static bool light_check(const float &transparency, const float &intensity)
Definition: lightmap.cpp:1739
static float light_calc(const float &numerator, const float &transparency, const int &distance)
Definition: lightmap.cpp:1732
void castLightWithLookup(Out(&output_cache)[MAPSIZE_X][MAPSIZE_Y], const T(&input_array)[MAPSIZE_X][MAPSIZE_Y], const diagonal_blocks(&blocked_array)[MAPSIZE_X][MAPSIZE_Y], const point &offset, int offsetDistance, T numerator=VISIBILITY_FULL, int row=1, float start=1.0f, float end=0.0f, T cumulative_transparency=LIGHT_TRANSPARENCY_OPEN_AIR)
Definition: lightmap.cpp:1383
direction
Definition: line.h:39
void update_light_quadrants(four_quadrants &update, const float &new_value, quadrant q)
Definition: shadowcasting.h:97
float accumulate_transparency(const float &cumulative_transparency, const float &current_transparency, const int &distance)

References accumulate_transparency(), castLightWithLookup(), get_cache(), light_calc(), light_check(), light_from_lookup(), MAPSIZE_X, MAPSIZE_Y, update_light_quadrants(), tripoint::xy(), and tripoint::z.

Referenced by generate_lightmap().

◆ apply_faction_ownership()

void map::apply_faction_ownership ( point  p1,
point  p2,
const faction_id id 
)

Definition at line 5332 of file mapgen.cpp.

5333{
5334 for( const tripoint &p : points_in_rectangle( tripoint( p1, abs_sub.z ), tripoint( p2,
5335 abs_sub.z ) ) ) {
5336 auto items = i_at( p.xy() );
5337 for( item &elem : items ) {
5338 elem.set_owner( id );
5339 }
5340 vehicle *source_veh = veh_pointer_or_null( veh_at( p ) );
5341 if( source_veh ) {
5342 if( !source_veh->has_owner() ) {
5343 source_veh->set_owner( id );
5344 }
5345 }
5346 }
5347}
tripoint_range< tripoint > points_in_rectangle(const tripoint &from, const tripoint &to) const
Definition: map.cpp:8752
bool has_owner() const
Definition: vehicle.h:552
void set_owner(const faction_id &new_owner)
Definition: vehicle.h:539

References abs_sub, vehicle::has_owner(), i_at(), points_in_rectangle(), vehicle::set_owner(), veh_at(), veh_pointer_or_null(), and tripoint::z.

Referenced by jmapgen_faction::apply().

◆ apply_light_arc()

void map::apply_light_arc ( const tripoint p,
units::angle  angle,
float  luminance,
units::angle  wideangle = 30_degrees 
)
private

Definition at line 1871 of file lightmap.cpp.

1873{
1874 if( luminance <= LIGHT_SOURCE_LOCAL ) {
1875 return;
1876 }
1877
1878 bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y] {};
1879
1881
1882 // Normalize (should work with negative values too)
1883 const units::angle wangle = wideangle / 2.0;
1884
1885 units::angle nangle = fmod( angle, 360_degrees );
1886
1887 tripoint end;
1888 int range = LIGHT_RANGE( luminance );
1889 calc_ray_end( nangle, range, p, end );
1890 apply_light_ray( lit, p, end, luminance );
1891
1892 tripoint test;
1893 calc_ray_end( wangle + nangle, range, p, test );
1894
1895 const float wdist = hypot( end.x - test.x, end.y - test.y );
1896 if( wdist <= 0.5 ) {
1897 return;
1898 }
1899
1900 // attempt to determine beam intensity required to cover all squares
1901 const units::angle wstep = ( wangle / ( wdist * M_SQRT2 ) );
1902
1903 // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter)
1904 for( units::angle ao = wstep; ao <= wangle; ao += wstep ) {
1905 if( trigdist ) {
1906 double fdist = ( ao * M_PI_2 ) / wangle;
1907 end.x = static_cast<int>(
1908 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle + ao ) );
1909 end.y = static_cast<int>(
1910 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle + ao ) );
1911 apply_light_ray( lit, p, end, luminance );
1912
1913 end.x = static_cast<int>(
1914 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle - ao ) );
1915 end.y = static_cast<int>(
1916 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle - ao ) );
1917 apply_light_ray( lit, p, end, luminance );
1918 } else {
1919 calc_ray_end( nangle + ao, range, p, end );
1920 apply_light_ray( lit, p, end, luminance );
1921 calc_ray_end( nangle - ao, range, p, end );
1922 apply_light_ray( lit, p, end, luminance );
1923 }
1924 }
1925}
bool trigdist
Circular distances.
@ range
Definition: character.h:104
void apply_light_ray(bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
Definition: lightmap.cpp:1927
static constexpr int LIGHTMAP_CACHE_Y
Definition: lightmap.cpp:50
static constexpr int LIGHTMAP_CACHE_X
Definition: lightmap.cpp:49
static constexpr float LIGHT_SOURCE_LOCAL
Definition: lightmap.h:8
#define LIGHT_RANGE(b)
Definition: lightmap.h:41
void calc_ray_end(units::angle angle, const int range, const tripoint &p, tripoint &out)
Definition: line.cpp:754
#define M_SQRT2
Definition: math_defines.h:29
#define M_PI_2
Definition: math_defines.h:25
quantity< double, angle_in_radians_tag > angle
Definition: units_angle.h:17
double sin(angle a)
Definition: units_angle.h:52
double cos(angle a)
Definition: units_angle.h:57
quantity< V, U > fmod(quantity< V, U > num, quantity< V, U > den)
Definition: units_def.h:142

References apply_light_ray(), apply_light_source(), calc_ray_end(), units::cos(), units::fmod(), LIGHT_RANGE, LIGHT_SOURCE_LOCAL, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, M_PI_2, M_SQRT2, range, units::sin(), trigdist, tripoint::x, and tripoint::y.

Referenced by add_light_from_items(), and generate_lightmap().

◆ apply_light_ray()

void map::apply_light_ray ( bool  lit[MAPSIZE_X][MAPSIZE_Y],
const tripoint s,
const tripoint e,
float  luminance 
)
private

Definition at line 1927 of file lightmap.cpp.

1929{
1930 point a( std::abs( e.x - s.x ) * 2, std::abs( e.y - s.y ) * 2 );
1931 point d( ( s.x < e.x ) ? 1 : -1, ( s.y < e.y ) ? 1 : -1 );
1932 point p( s.xy() );
1933
1934 quadrant quad = quadrant_from_x_y( d.x, d.y );
1935
1936 // TODO: Invert that z comparison when it's sane
1937 if( s.z != e.z || ( s.x == e.x && s.y == e.y ) ) {
1938 return;
1939 }
1940
1941 auto &lm = get_cache( s.z ).lm;
1942 auto &transparency_cache = get_cache( s.z ).transparency_cache;
1943
1944 float distance = 1.0;
1945 float transparency = LIGHT_TRANSPARENCY_OPEN_AIR;
1946 const float scaling_factor = static_cast<float>( rl_dist( s, e ) ) /
1947 static_cast<float>( square_dist( s, e ) );
1948 // TODO: [lightmap] Pull out the common code here rather than duplication
1949 if( a.x > a.y ) {
1950 int t = a.y - ( a.x / 2 );
1951 do {
1952 if( t >= 0 ) {
1953 p.y += d.y;
1954 t -= a.x;
1955 }
1956
1957 p.x += d.x;
1958 t += a.y;
1959
1960 // TODO: clamp coordinates to map bounds before this method is called.
1961 if( lightmap_boundaries.contains( p ) ) {
1962 float current_transparency = transparency_cache[p.x][p.y];
1963 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1964 if( !lit[p.x][p.y] ) {
1965 // Multiple rays will pass through the same squares so we need to record that
1966 lit[p.x][p.y] = true;
1967 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1968 quadrant q = is_opaque ? quad : quadrant::default_;
1969 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1970 }
1971 if( is_opaque ) {
1972 break;
1973 }
1974 // Cumulative average of the transparency values encountered.
1975 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1976 } else {
1977 break;
1978 }
1979
1980 distance += scaling_factor;
1981 } while( !( p.x == e.x && p.y == e.y ) );
1982 } else {
1983 int t = a.x - ( a.y / 2 );
1984 do {
1985 if( t >= 0 ) {
1986 p.x += d.x;
1987 t -= a.y;
1988 }
1989
1990 p.y += d.y;
1991 t += a.x;
1992
1993 if( lightmap_boundaries.contains( p ) ) {
1994 float current_transparency = transparency_cache[p.x][p.y];
1995 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1996 if( !lit[p.x][p.y] ) {
1997 // Multiple rays will pass through the same squares so we need to record that
1998 lit[p.x][p.y] = true;
1999 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
2000 quadrant q = is_opaque ? quad : quadrant::default_;
2001 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
2002 }
2003 if( is_opaque ) {
2004 break;
2005 }
2006 // Cumulative average of the transparency values encountered.
2007 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
2008 } else {
2009 break;
2010 }
2011
2012 distance += scaling_factor;
2013 } while( !( p.x == e.x && p.y == e.y ) );
2014 }
2015}
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505
static constexpr quadrant quadrant_from_x_y(int x, int y)
Definition: lightmap.cpp:876
static float fastexp(float x)
Definition: lightmap.cpp:1716
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36
quadrant
Definition: shadowcasting.h:22

References a, default_, fastexp(), get_cache(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, quadrant_from_x_y(), rl_dist(), square_dist(), level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by apply_light_arc().

◆ apply_light_source()

void map::apply_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 1750 of file lightmap.cpp.

1751{
1752 auto &cache = get_cache( p.z );
1753 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1754 float ( &sm )[MAPSIZE_X][MAPSIZE_Y] = cache.sm;
1755 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1756 float ( &light_source_buffer )[MAPSIZE_X][MAPSIZE_Y] = cache.light_source_buffer;
1757 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.vehicle_obscured_cache;
1758
1759 const point p2( p.xy() );
1760
1761 if( inbounds( p ) ) {
1762 const float min_light = std::max( static_cast<float>( lit_level::LOW ), luminance );
1763 lm[p2.x][p2.y] = elementwise_max( lm[p2.x][p2.y], min_light );
1764 sm[p2.x][p2.y] = std::max( sm[p2.x][p2.y], luminance );
1765 }
1766 if( luminance <= lit_level::LOW ) {
1767 return;
1768 } else if( luminance <= lit_level::BRIGHT_ONLY ) {
1769 luminance = 1.49f;
1770 }
1771
1772 /* If we're a 5 luminance fire , we skip casting rays into ey && sx if we have
1773 neighboring fires to the north and west that were applied via light_source_buffer
1774 If there's a 1 luminance candle east in buffer, we still cast rays into ex since it's smaller
1775 If there's a 100 luminance magnesium flare south added via apply_light_source instead od
1776 add_light_source, it's unbuffered so we'll still cast rays into sy.
1777
1778 ey
1779 nnnNnnn
1780 w e
1781 w 5 +e
1782 sx W 5*1+E ex
1783 w ++++e
1784 w+++++e
1785 sssSsss
1786 sy
1787 */
1788 const int peer_inbounds = LIGHTMAP_CACHE_X - 1;
1789 bool north = ( p2.y != 0 && light_source_buffer[p2.x][p2.y - 1] < luminance );
1790 bool south = ( p2.y != peer_inbounds && light_source_buffer[p2.x][p2.y + 1] < luminance );
1791 bool east = ( p2.x != peer_inbounds && light_source_buffer[p2.x + 1][p2.y] < luminance );
1792 bool west = ( p2.x != 0 && light_source_buffer[p2.x - 1][p2.y] < luminance );
1793
1794 if( north ) {
1797 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1800 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1801 }
1802
1803 if( east ) {
1806 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1809 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1810 }
1811
1812 if( south ) {
1815 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1818 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1819 }
1820
1821 if( west ) {
1824 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1827 lm, transparency_cache, blocked_cache, p2, 0, luminance );
1828 }
1829}
constexpr scale sm
Definition: coordinates.h:31

References accumulate_transparency(), BRIGHT_ONLY, castLightWithLookup(), get_cache(), inbounds(), light_calc(), light_check(), light_from_lookup(), LIGHTMAP_CACHE_X, LOW, MAPSIZE_X, MAPSIZE_Y, coords::sm, update_light_quadrants(), point::x, tripoint::xy(), point::y, and tripoint::z.

Referenced by apply_character_light(), apply_light_arc(), and generate_lightmap().

◆ apply_vision_transparency_cache()

void map::apply_vision_transparency_cache ( const tripoint center,
int  target_z,
float(&)  vision_restore_cache[9],
bool(&)  blocked_restore_cache[8] 
)
protected

Definition at line 1467 of file lightmap.cpp.

1469{
1470 level_cache &map_cache = get_cache( target_z );
1471 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1472 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1473
1474 int i = 0;
1475 for( point adjacent : eight_adjacent_offsets ) {
1476 const tripoint p = center + adjacent;
1477 if( !inbounds( p ) ) {
1478 continue;
1479 }
1480 vision_restore_cache[i] = transparency_cache[p.x][p.y];
1482 transparency_cache[p.x][p.y] = LIGHT_TRANSPARENCY_SOLID;
1484
1486 adjacent ) == four_diagonal_offsets.end() ) {
1487 debugmsg( "Hidden tile not on a diagonal" );
1488 continue;
1489 }
1490
1491 bool &relevant_blocked = adjacent == point_north_east ? blocked_cache[center.x][center.y].ne :
1492 adjacent == point_south_east ? blocked_cache[p.x][p.y].nw :
1493 adjacent == point_south_west ? blocked_cache[p.x][p.y].ne :
1494 /* point_north_west */ blocked_cache[center.x][center.y].nw;
1495
1496 //We only set the restore cache if we actually flip the bit
1497 blocked_restore_cache[i] = !relevant_blocked;
1498
1499 relevant_blocked = true;
1500 }
1501 i++;
1502 }
1503 vision_restore_cache[8] = transparency_cache[center.x][center.y];
1504}
vision_adjustment vision_transparency_cache[8]
Definition: map.h:1791
@ VISION_ADJUST_HIDDEN
Definition: lightmap.h:79
@ VISION_ADJUST_SOLID
Definition: lightmap.h:78
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)
static constexpr std::array< point, 8 > eight_adjacent_offsets
Definition: point.h:352
static constexpr std::array< point, 4 > four_diagonal_offsets
Definition: point.h:348
diagonal_blocks vehicle_obscured_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:336

References center, debugmsg, eight_adjacent_offsets, detail::find(), four_diagonal_offsets, get_cache(), inbounds(), LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, point_north_east, point_south_east, point_south_west, level_cache::transparency_cache, level_cache::vehicle_obscured_cache, VISION_ADJUST_HIDDEN, VISION_ADJUST_SOLID, vision_transparency_cache, tripoint::x, and tripoint::y.

Referenced by build_seen_cache().

◆ bash()

bash_results map::bash ( const tripoint p,
int  str,
bool  silent = false,
bool  destroy = false,
bool  bash_floor = false,
const vehicle bashing_vehicle = nullptr 
)

Returns a pair where first is whether anything was smashed and second is if it was destroyed.

Parameters
pWhere to bash
strHow hard to bash
silentDon't produce any sound
destroyDestroys some otherwise unbashable tiles
bash_floorAllow bashing the floor and the tile that supports it
bashing_vehicleVehicle that should NOT be bashed (because it is doing the bashing)

Definition at line 3624 of file map.cpp.

3627{
3628 bash_params bsh{
3629 str, silent, destroy, bash_floor, static_cast<float>( rng_float( 0, 1.0f ) ), false, true
3630 };
3632 if( !inbounds( p ) ) {
3633 return result;
3634 }
3635
3636 bool bashed_sealed = false;
3637 if( has_flag( "SEALED", p ) ) {
3638 result |= bash_ter_furn( p, bsh );
3639 bashed_sealed = true;
3640 }
3641
3642 result |= bash_field( p, bsh );
3643
3644 // Don't bash items inside terrain/furniture with SEALED flag
3645 if( !bashed_sealed ) {
3646 result |= bash_items( p, bsh );
3647 }
3648 // Don't bash the vehicle doing the bashing
3649 const vehicle *veh = veh_pointer_or_null( veh_at( p ) );
3650 if( veh != nullptr && veh != bashing_vehicle ) {
3651 result |= bash_vehicle( p, bsh );
3652 }
3653
3654 // If we still didn't bash anything solid (a vehicle) or a tile with SEALED flag, bash ter/furn
3655 if( !result.bashed_solid && !bashed_sealed ) {
3656 result |= bash_ter_furn( p, bsh );
3657 }
3658
3659 return result;
3660}
bash_results bash_field(const tripoint &p, const bash_params &params)
Definition: map.cpp:3714
bash_results bash_items(const tripoint &p, const bash_params &params)
Definition: map.cpp:3662
bash_results bash_vehicle(const tripoint &p, const bash_params &params)
Definition: map.cpp:3696
bash_results bash_ter_furn(const tripoint &p, const bash_params &params)
Definition: map.cpp:3500
double rng_float(double lo, double hi)
Definition: rng.cpp:28
@ silent
Definition: weather_type.h:56

References bash_field(), bash_items(), bash_ter_furn(), bash_vehicle(), destroy(), has_flag(), inbounds(), rng_float(), silent, veh_at(), and veh_pointer_or_null().

Referenced by jmapgen_setmap::apply(), spell_effect::bash(), bash_furn_success(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), batter(), destroy(), destroy_furn(), drop_furniture(), drop_items(), game::fling_creature(), is_bashable(), game::knockback(), route(), shoot(), and valid_move().

◆ bash_field()

bash_results map::bash_field ( const tripoint p,
const bash_params params 
)

Definition at line 3714 of file map.cpp.

3715{
3717 if( get_field( p, fd_web ) != nullptr ) {
3718 result.did_bash = true;
3719 result.bashed_solid = true; // To prevent bashing furniture/vehicles
3720 remove_field( p, fd_web );
3721 }
3722
3723 return result;
3724}
void remove_field(const tripoint &p, const field_type_id &field_to_remove)
Remove field entry at xy, ignored if the field entry is not present.
Definition: map.cpp:5593
field_type_id fd_web
Definition: field_type.cpp:340

References fd_web, get_field(), and remove_field().

Referenced by bash().

◆ bash_furn_success()

bash_results map::bash_furn_success ( const tripoint p,
const bash_params params 
)

Definition at line 3400 of file map.cpp.

3401{
3403 const auto &furnid = furn( p ).obj();
3404 const map_bash_info &bash = furnid.bash;
3405
3406
3407 if( has_flag_furn( "FUNGUS", p ) ) {
3408 fungal_effects( *g, *this ).create_spores( p );
3409 }
3410 if( has_flag_furn( "MIGO_NERVE", p ) ) {
3411 map_funcs::migo_nerve_cage_removal( *this, p, true );
3412 }
3413 std::string soundfxvariant = furnid.id.str();
3414 const bool tent = !bash.tent_centers.empty();
3415
3416 // Special code to collapse the tent if destroyed
3417 if( tent ) {
3418 // Get ids of possible centers
3419 std::set<furn_id> centers;
3420 for( const auto &cur_id : bash.tent_centers ) {
3421 if( cur_id.is_valid() ) {
3422 centers.insert( cur_id );
3423 }
3424 }
3425
3426 std::optional<std::pair<tripoint, furn_id>> tentp;
3427
3428 // Find the center of the tent
3429 // First check if we're not currently bashing the center
3430 if( centers.count( furn( p ) ) > 0 ) {
3431 tentp.emplace( p, furn( p ) );
3432 } else {
3433 for( const tripoint &pt : points_in_radius( p, bash.collapse_radius ) ) {
3434 const furn_id &f_at = furn( pt );
3435 // Check if we found the center of the current tent
3436 if( centers.count( f_at ) > 0 ) {
3437 tentp.emplace( pt, f_at );
3438 break;
3439 }
3440 }
3441 }
3442 // Didn't find any tent center, wreck the current tile
3443 if( !tentp ) {
3445 furn_set( p, bash.furn_set );
3446 } else {
3447 // Take the tent down
3448 const int rad = tentp->second.obj().bash.collapse_radius;
3449 for( const tripoint &pt : points_in_radius( tentp->first, rad ) ) {
3450 const furn_id frn = furn( pt );
3451 if( frn == f_null ) {
3452 continue;
3453 }
3454
3455 const map_bash_info &recur_bash = frn.obj().bash;
3456 // Check if we share a center type and thus a "tent type"
3457 for( const auto &cur_id : recur_bash.tent_centers ) {
3458 if( centers.count( cur_id.id() ) > 0 ) {
3459 // Found same center, wreck current tile
3461 furn_set( pt, recur_bash.furn_set );
3462 break;
3463 }
3464 }
3465 }
3466 }
3467 soundfxvariant = "smash_cloth";
3468 } else {
3469 furn_set( p, bash.furn_set );
3470 for( item &it : i_at( p ) ) {
3471 it.on_drop( p, *this );
3472 }
3473 // HACK: Hack alert.
3474 // Signs have cosmetics associated with them on the submap since
3475 // furniture can't store dynamic data to disk. To prevent writing
3476 // mysteriously appearing for a sign later built here, remove the
3477 // writing from the submap.
3478 delete_signage( p );
3479 }
3480
3481 if( !tent ) {
3483 }
3484
3485 if( !bash.sound.empty() && !params.silent ) {
3486 static const std::string soundfxid = "smash_success";
3487 int sound_volume = get_sound_volume( bash );
3488 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3489 soundfxid, soundfxvariant );
3490 }
3491
3492 if( bash.explosive > 0 ) {
3493 // TODO implement if the player triggered the explosive furniture
3494 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3495 }
3496
3497 return result;
3498}
void create_spores(const tripoint &p, Creature *origin=nullptr)
Makes spores at p.
bool has_flag_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2399
bash_results bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:3624
std::vector< item * > spawn_items(const tripoint &p, const std::vector< item > &new_items)
Definition: map.cpp:4283
void furn_set(const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
Sets the furniture at given position.
Definition: map.cpp:1425
void delete_signage(const tripoint &p) const
Definition: map.cpp:4142
static int get_sound_volume(const map_bash_info &bash)
Definition: map.cpp:3262
furn_id f_null
Definition: mapdata.cpp:1098
void explosion(const tripoint &p, Creature *source, float power, float factor, bool fire, int legacy_casing_mass, float)
Legacy explosion function.
Definition: explosion.cpp:1080
ItemList items_from(const item_group_id &group_id, const time_point &birthday)
Create items from the given group.
Definition: item_group.cpp:574
void migo_nerve_cage_removal(map &m, const tripoint &p, bool spawn_damaged)
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:178
@ rad
Must be irradiated/in irradiated tile.
bool silent
Definition: map.h:136
std::vector< furn_str_id > tent_centers
Definition: mapdata.h:101
item_group_id drop_group
Definition: mapdata.h:87
furn_str_id furn_set
Definition: mapdata.h:99
map_bash_info bash
Definition: mapdata.h:348

References bash(), map_data_common_t::bash, sounds::combat, fungal_effects::create_spores(), delete_signage(), map_bash_info::drop_group, explosion_handler::explosion(), f_null, furn(), furn_set(), map_bash_info::furn_set, g, get_sound_volume(), has_flag_furn(), i_at(), item_group::items_from(), map_funcs::migo_nerve_cage_removal(), int_id< T >::obj(), points_in_radius(), rad, bash_params::silent, sounds::sound(), spawn_items(), map_bash_info::tent_centers, and calendar::turn.

Referenced by bash_ter_furn().

◆ bash_items()

bash_results map::bash_items ( const tripoint p,
const bash_params params 
)

Definition at line 3662 of file map.cpp.

3663{
3665 if( !has_items( p ) ) {
3666 return result;
3667 }
3668
3669 std::vector<item> smashed_contents;
3670 auto bashed_items = i_at( p );
3671 bool smashed_glass = false;
3672 for( auto bashed_item = bashed_items.begin(); bashed_item != bashed_items.end(); ) {
3673 // the check for active suppresses Molotovs smashing themselves with their own explosion
3674 if( bashed_item->made_of( material_id( "glass" ) ) && !bashed_item->active && one_in( 2 ) ) {
3675 result.did_bash = true;
3676 smashed_glass = true;
3677 for( const item *bashed_content : bashed_item->contents.all_items_top() ) {
3678 smashed_contents.push_back( item( *bashed_content ) );
3679 }
3680 bashed_item = bashed_items.erase( bashed_item );
3681 } else {
3682 ++bashed_item;
3683 }
3684 }
3685 // Now plunk in the contents of the smashed items.
3686 spawn_items( p, smashed_contents );
3687
3688 // Add a glass sound even when something else also breaks
3689 if( smashed_glass && !params.silent ) {
3690 sounds::sound( p, 12, sounds::sound_t::combat, _( "glass shattering" ), false,
3691 "smash_success", "smash_glass_contents" );
3692 }
3693 return result;
3694}
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
item_contents contents
Definition: item.h:2171
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:4891

References _, item_contents::all_items_top(), sounds::combat, item::contents, has_items(), i_at(), one_in(), bash_params::silent, sounds::sound(), and spawn_items().

Referenced by bash().

◆ bash_rating() [1/2]

int map::bash_rating ( const int  str,
point  p 
) const
inline

Definition at line 992 of file map.h.

992 {
993 return bash_rating( str, tripoint( p, abs_sub.z ) );
994 }
int bash_rating(int str, const tripoint &p, bool allow_floor=false) const
Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement...
Definition: map.cpp:2571

References abs_sub, bash_rating(), and tripoint::z.

◆ bash_rating() [2/2]

int map::bash_rating ( int  str,
const tripoint p,
bool  allow_floor = false 
) const

Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down.

-1 means the square is not bashable

Definition at line 2571 of file map.cpp.

2572{
2573 if( !inbounds( p ) ) {
2574 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2575 return -1;
2576 }
2577
2578 if( str <= 0 ) {
2579 return -1;
2580 }
2581
2582 const furn_t &furniture = furn( p ).obj();
2583 const ter_t &terrain = ter( p ).obj();
2584 const optional_vpart_position vp = veh_at( p );
2585 vehicle *const veh = vp ? &vp->vehicle() : nullptr;
2586 const int part = vp ? vp->part_index() : -1;
2587 return bash_rating_internal( str, furniture, terrain, allow_floor, veh, part );
2588}
int bash_rating_internal(int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
Definition: map.cpp:2462

References bash_rating_internal(), dbg, furn(), furniture, inbounds(), int_id< T >::obj(), ter(), terrain, veh_at(), and Warn.

Referenced by bash_rating().

◆ bash_rating_internal()

int map::bash_rating_internal ( int  str,
const furn_t furniture,
const ter_t terrain,
bool  allow_floor,
const vehicle veh,
int  part 
) const
private
Strength determines what furniture can be smashed Strength determines what terrain can be smashed Strength increases smashing damage

Definition at line 2462 of file map.cpp.

2465{
2466 bool furn_smash = false;
2467 bool ter_smash = false;
2468 ///\EFFECT_STR determines what furniture can be smashed
2469 if( furniture.id && furniture.bash.str_max != -1 ) {
2470 furn_smash = true;
2471 ///\EFFECT_STR determines what terrain can be smashed
2472 } else if( terrain.bash.str_max != -1 && ( !terrain.bash.bash_below || allow_floor ) ) {
2473 ter_smash = true;
2474 }
2475
2476 if( veh != nullptr && vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part() ) {
2477 // Monsters only care about rating > 0, NPCs should want to path around cars instead
2478 return 2; // Should probably be a function of part hp (+armor on tile)
2479 }
2480
2481 int bash_min = 0;
2482 int bash_max = 0;
2483 if( furn_smash ) {
2484 bash_min = furniture.bash.str_min;
2485 bash_max = furniture.bash.str_max;
2486 } else if( ter_smash ) {
2487 bash_min = terrain.bash.str_min;
2488 bash_max = terrain.bash.str_max;
2489 } else {
2490 return -1;
2491 }
2492
2493 ///\EFFECT_STR increases smashing damage
2494 if( str < bash_min ) {
2495 return 0;
2496 } else if( str >= bash_max ) {
2497 return 10;
2498 }
2499
2500 int ret = ( 10 * ( str - bash_min ) ) / ( bash_max - bash_min );
2501 // Round up to 1, so that desperate NPCs can try to bash down walls
2502 return std::max( ret, 1 );
2503}
Reference to a position (a point) of the vehicle.

References furniture, cata::hash64_detail::ret, and terrain.

Referenced by bash_rating(), and route().

◆ bash_resistance() [1/2]

int map::bash_resistance ( const tripoint p,
bool  allow_floor = false 
) const

Returns min_str of the furniture or terrain at p.

Definition at line 2557 of file map.cpp.

2558{
2559 if( has_furn( p ) && furn( p ).obj().bash.str_min != -1 ) {
2560 return furn( p ).obj().bash.str_min;
2561 }
2562
2563 const auto &ter_bash = ter( p ).obj().bash;
2564 if( ter_bash.str_min != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2565 return ter_bash.str_min;
2566 }
2567
2568 return -1;
2569}
bool has_furn(const tripoint &p) const
Definition: map.cpp:1408
int str_min
Definition: mapdata.h:63

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_min, and ter().

Referenced by bash_resistance(), and rate_location().

◆ bash_resistance() [2/2]

int map::bash_resistance ( point  p) const
inline

Definition at line 986 of file map.h.

986 {
987 return bash_resistance( tripoint( p, abs_sub.z ) );
988 }
int bash_resistance(const tripoint &p, bool allow_floor=false) const
Returns min_str of the furniture or terrain at p.
Definition: map.cpp:2557

References abs_sub, bash_resistance(), and tripoint::z.

◆ bash_strength() [1/2]

int map::bash_strength ( const tripoint p,
bool  allow_floor = false 
) const

Returns max_str of the furniture or terrain at p.

Definition at line 2543 of file map.cpp.

2544{
2545 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2546 return furn( p ).obj().bash.str_max;
2547 }
2548
2549 const auto &ter_bash = ter( p ).obj().bash;
2550 if( ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2551 return ter_bash.str_max;
2552 }
2553
2554 return -1;
2555}
int str_max
Definition: mapdata.h:65

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by bash_strength(), and game::fling_creature().

◆ bash_strength() [2/2]

int map::bash_strength ( point  p) const
inline

Definition at line 981 of file map.h.

981 {
982 return bash_strength( tripoint( p, abs_sub.z ) );
983 }
int bash_strength(const tripoint &p, bool allow_floor=false) const
Returns max_str of the furniture or terrain at p.
Definition: map.cpp:2543

References abs_sub, bash_strength(), and tripoint::z.

◆ bash_ter_furn()

bash_results map::bash_ter_furn ( const tripoint p,
const bash_params params 
)

Definition at line 3500 of file map.cpp.

3501{
3503 std::string soundfxvariant;
3504 const auto &ter_obj = ter( p ).obj();
3505 const auto &furn_obj = furn( p ).obj();
3506 bool smash_ter = false;
3507 const map_bash_info *bash = nullptr;
3508
3509 if( furn_obj.id && furn_obj.bash.str_max != -1 ) {
3510 bash = &furn_obj.bash;
3511 soundfxvariant = furn_obj.id.str();
3512 } else if( ter_obj.bash.str_max != -1 ) {
3513 bash = &ter_obj.bash;
3514 smash_ter = true;
3515 soundfxvariant = ter_obj.id.str();
3516 }
3517
3518 // Floor bashing check
3519 // Only allow bashing floors when we want to bash floors and we're in z-level mode
3520 // Unless we're destroying, then it gets a little weird
3521 if( smash_ter && bash->bash_below && ( !zlevels || !params.bash_floor ) ) {
3522 if( !params.destroy ) {
3523 smash_ter = false;
3524 bash = nullptr;
3525 } else if( !bash->ter_set && zlevels ) {
3526 // HACK: A hack for destroy && !bash_floor
3527 // We have to check what would we create and cancel if it is what we have now
3528 tripoint below( p.xy(), p.z - 1 );
3529 const auto roof = get_roof( below, false );
3530 if( roof == ter( p ) ) {
3531 smash_ter = false;
3532 bash = nullptr;
3533 }
3534 } else if( !bash->ter_set && ter( p ) == t_dirt ) {
3535 // As above, except for no-z-levels case
3536 smash_ter = false;
3537 bash = nullptr;
3538 }
3539 }
3540
3541 // TODO: what if silent is true?
3542 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3543 sounds::sound( p, 40, sounds::sound_t::alarm, _( "an alarm go off!" ),
3544 false, "environment", "alarm" );
3545 // Blame nearby player
3546 if( rl_dist( g->u.pos(), p ) <= 3 ) {
3547 g->events().send<event_type::triggers_alarm>( g->u.getID() );
3548 const point abs = ms_to_sm_copy( getabs( p.xy() ) );
3549 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0,
3550 tripoint( abs, p.z ) );
3551 }
3552 }
3553
3554 if( bash == nullptr || ( bash->destroy_only && !params.destroy ) ) {
3555 // Nothing bashable here
3556 if( impassable( p ) ) {
3557 if( !params.silent ) {
3558 sounds::sound( p, 18, sounds::sound_t::combat, _( "thump!" ),
3559 false, "smash_fail", "default" );
3560 }
3561
3562 result.did_bash = true;
3563 result.bashed_solid = true;
3564 }
3565
3566 return result;
3567 }
3568
3569 result.did_bash = true;
3570 result.bashed_solid = true;
3571 result.success = params.destroy;
3572
3573 int smin = bash->str_min;
3574 int smax = bash->str_max;
3575 if( !params.destroy ) {
3576 if( bash->str_min_blocked != -1 || bash->str_max_blocked != -1 ) {
3577 if( furn_is_supported( *this, p ) ) {
3578 if( bash->str_min_blocked != -1 ) {
3579 smin = bash->str_min_blocked;
3580 }
3581 if( bash->str_max_blocked != -1 ) {
3582 smax = bash->str_max_blocked;
3583 }
3584 }
3585 }
3586
3587 if( bash->str_min_supported != -1 || bash->str_max_supported != -1 ) {
3588 tripoint below( p.xy(), p.z - 1 );
3589 if( !zlevels || has_flag( TFLAG_SUPPORTS_ROOF, below ) ) {
3590 if( bash->str_min_supported != -1 ) {
3591 smin = bash->str_min_supported;
3592 }
3593 if( bash->str_max_supported != -1 ) {
3594 smax = bash->str_max_supported;
3595 }
3596 }
3597 }
3598 // Linear interpolation from str_min to str_max
3599 const int resistance = smin + ( params.roll * ( smax - smin ) );
3600 if( params.strength >= resistance ) {
3601 result.success = true;
3602 }
3603 }
3604
3605 if( !result.success ) {
3606 int sound_volume = bash->sound_fail_vol.value_or( 12 );
3607
3608 result.did_bash = true;
3609 if( !params.silent ) {
3610 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash->sound_fail, false,
3611 "smash_fail", soundfxvariant );
3612 }
3613 } else {
3614 if( smash_ter ) {
3615 result |= bash_ter_success( p, params );
3616 } else {
3617 result |= bash_furn_success( p, params );
3618 }
3619 }
3620
3621 return result;
3622}
ter_id get_roof(const tripoint &p, bool allow_air) const
Definition: map.cpp:3202
bash_results bash_furn_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3400
bash_results bash_ter_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3270
point ms_to_sm_copy(point p)
static bool furn_is_supported(const map &m, const tripoint &p)
Definition: map.cpp:3246
ter_id t_dirt
Definition: mapdata.cpp:628
@ TFLAG_SUPPORTS_ROOF
Definition: mapdata.h:281
float roll
Value from 0.0 to 1.0 that affects interpolation between str_min and str_max At 0....
Definition: map.h:147
bool bash_floor
Definition: map.h:140
bool destroy
Definition: map.h:138
int strength
Definition: map.h:134
@ TIMED_EVENT_WANTED
Definition: timed_event.h:13

References _, sounds::alarm, bash(), bash_params::bash_floor, bash_furn_success(), bash_ter_success(), sounds::combat, bash_params::destroy, furn(), furn_is_supported(), g, get_roof(), getabs(), has_flag(), impassable(), ms_to_sm_copy(), int_id< T >::obj(), rl_dist(), bash_params::roll, bash_params::silent, sounds::sound(), bash_params::strength, t_dirt, ter(), TFLAG_SUPPORTS_ROOF, TIMED_EVENT_WANTED, triggers_alarm, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash(), and bash_ter_success().

◆ bash_ter_success()

bash_results map::bash_ter_success ( const tripoint p,
const bash_params params 
)

Definition at line 3270 of file map.cpp.

3271{
3273 result.success = true;
3274 const ter_t &ter_before = ter( p ).obj();
3275 const map_bash_info &bash = ter_before.bash;
3276 if( has_flag_ter( "FUNGUS", p ) ) {
3277 fungal_effects( *g, *this ).create_spores( p );
3278 }
3279 const std::string soundfxvariant = ter_before.id.str();
3280 const bool will_collapse = ter_before.has_flag( TFLAG_SUPPORTS_ROOF ) &&
3281 !ter_before.has_flag( TFLAG_INDOORS );
3282 const bool suspended = ter_before.has_flag( TFLAG_SUSPENDED );
3283 bool follow_below = false;
3284 if( params.bashing_from_above && bash.ter_set_bashed_from_above ) {
3285 // If this terrain is being bashed from above and this terrain
3286 // has a valid post-destroy bashed-from-above terrain, set it
3287 ter_set( p, bash.ter_set_bashed_from_above );
3288 } else if( bash.ter_set ) {
3289 // If the terrain has a valid post-destroy terrain, set it
3290 ter_set( p, bash.ter_set );
3291 follow_below |= zlevels && bash.bash_below;
3292 } else if( suspended ) {
3293 // Its important that we change the ter value before recursing, otherwise we'll hit an infinite loop.
3294 // This could be prevented by assembling a visited list, but in order to avoid that cost, we're going
3295 // build our recursion to just be resilient.
3296 ter_set( p, t_open_air );
3298 } else {
3299 tripoint below( p.xy(), p.z - 1 );
3300 const ter_t &ter_below = ter( below ).obj();
3301 // Only setting the flag here because we want drops and sounds in correct order
3302 follow_below |= zlevels && bash.bash_below && ter_below.roof;
3303
3304 ter_set( p, t_open_air );
3305 }
3306
3308
3309 if( !bash.sound.empty() && !params.silent ) {
3310 static const std::string soundfxid = "smash_success";
3311 int sound_volume = get_sound_volume( bash );
3312 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3313 soundfxid, soundfxvariant );
3314 }
3315
3316 if( !zlevels ) {
3317 if( ter( p ) == t_open_air ) {
3318 // We destroyed something, so we aren't just "plugging" air with dirt here
3319 ter_set( p, t_dirt );
3320 }
3321 } else if( follow_below || ter( p ) == t_open_air ) {
3322 const tripoint below( p.xy(), p.z - 1 );
3323 // We may need multiple bashes in some weird cases
3324 // Example:
3325 // W has roof A
3326 // A bashes to B
3327 // B bashes to nothing
3328 // Below our point P, there is a W
3329 // If we bash down a B over a W, it might be from earlier A or just constructed over it!
3330 //
3331 // Current solution: bash roof until you reach same roof type twice, then bash down
3332 if( follow_below && params.do_recurse ) {
3333 bool blocked_by_roof = false;
3334 std::set<ter_id> encountered_types;
3335 encountered_types.insert( ter_before.id );
3336 encountered_types.insert( t_open_air );
3337 // Note: we're bashing the new roof, not the tile supported by it!
3338 int down_bash_tries = 10;
3339 do {
3340 const ter_id &ter_now = ter( p );
3341 if( encountered_types.count( ter_now ) != 0 ) {
3342 // We have encountered this type before and destroyed it (didn't block us)
3343 ter_set( p, t_open_air );
3344 bash_params params_below = params;
3345 params_below.bashing_from_above = true;
3346 params_below.bash_floor = false;
3347 params_below.do_recurse = false;
3348 params_below.destroy = true;
3349 int impassable_bash_tries = 10;
3350 // Unconditionally destroy, but don't go deeper
3351 do {
3352 result |= bash_ter_success( below, params_below );
3353 } while( ter( below )->movecost == 0 && impassable_bash_tries-- > 0 );
3354 if( impassable_bash_tries <= 0 ) {
3355 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3356 }
3357 } else if( ter_now == t_open_air ) {
3358 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3359 if( roof != t_open_air ) {
3360 ter_set( p, roof );
3361 }
3362 } else {
3363 // This floor/roof tile wasn't destroyed in this loop yet
3364 encountered_types.insert( ter_now );
3365 bash_params params_copy = params;
3366 params_copy.do_recurse = false;
3367 // TODO: Unwrap the calls, don't recurse
3368 // TODO: Don't bash furn
3369 bash_results results_sub = bash_ter_furn( p, params_copy );
3370 result |= results_sub;
3371 if( !results_sub.success ) {
3372 // Blocked, as in "the roof was too strong to bash"
3373 blocked_by_roof = true;
3374 }
3375 }
3376 } while( down_bash_tries-- > 0 && !blocked_by_roof &&
3377 ( ter( p ) != t_open_air || ter( p )->movecost == 0 || ter( below )->roof ) );
3378 if( down_bash_tries <= 0 ) {
3379 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3380 }
3381 } else {
3382 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3383
3384 ter_set( p, roof );
3385 }
3386 }
3387
3388 if( will_collapse && !has_flag( TFLAG_SUPPORTS_ROOF, p ) ) {
3389 collapse_at( p, params.silent, true, bash.explosive > 0 );
3390 }
3391
3392 if( bash.explosive > 0 ) {
3393 // TODO Implement if the player triggered the explosive terrain
3394 explosion_handler::explosion( p, nullptr, bash.explosive, 0.8, false );
3395 }
3396
3397 return result;
3398}
void propagate_suspension_check(const tripoint &point)
Checks surrounding tiles for suspension, and has them check for collapse.
Definition: map.cpp:3006
void collapse_at(const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
Causes a collapse at p, such as from destroying a wall.
Definition: map.cpp:2961
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:263
@ TFLAG_SUSPENDED
Definition: mapdata.h:324
@ TFLAG_INDOORS
Definition: mapdata.h:292
bool do_recurse
Hack to prevent infinite recursion.
Definition: map.h:159
bool bashing_from_above
Definition: map.h:154
bool success
Definition: map.h:170
bool has_flag(const std::string &flag) const
Definition: mapdata.h:421
ter_str_id id
Definition: mapdata.h:467

References bash(), map_data_common_t::bash, bash_params::bash_floor, bash_ter_furn(), bash_ter_success(), bash_params::bashing_from_above, collapse_at(), sounds::combat, fungal_effects::create_spores(), debugmsg, bash_params::destroy, bash_params::do_recurse, explosion_handler::explosion(), g, get_roof(), get_sound_volume(), map_data_common_t::has_flag(), has_flag(), has_flag_ter(), ter_t::id, item_group::items_from(), int_id< T >::obj(), propagate_suspension_check(), ter_t::roof, bash_params::silent, sounds::sound(), spawn_items(), string_id< T >::str(), bash_results::success, t_dirt, t_open_air, ter(), ter_set(), TFLAG_INDOORS, TFLAG_SUPPORTS_ROOF, TFLAG_SUSPENDED, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash_ter_furn(), bash_ter_success(), and shoot().

◆ bash_vehicle()

bash_results map::bash_vehicle ( const tripoint p,
const bash_params params 
)

Definition at line 3696 of file map.cpp.

3697{
3699 // Smash vehicle if present
3700 if( const optional_vpart_position vp = veh_at( p ) ) {
3701 vp->vehicle().damage( vp->part_index(), params.strength, DT_BASH );
3702 if( !params.silent ) {
3703 sounds::sound( p, 18, sounds::sound_t::combat, _( "crash!" ), false,
3704 "smash_success", "hit_vehicle" );
3705 }
3706
3707 result.did_bash = true;
3708 result.success = true;
3709 result.bashed_solid = true;
3710 }
3711 return result;
3712}
@ DT_BASH
Definition: damage.h:24

References _, sounds::combat, DT_BASH, bash_params::silent, sounds::sound(), bash_params::strength, and veh_at().

Referenced by bash().

◆ batter()

void map::batter ( const tripoint p,
int  power,
int  tries = 1,
bool  silent = false 
)

bash a square for a set number of times at set power.

Does not destroy

Definition at line 3761 of file map.cpp.

3762{
3763 int count = 0;
3764 while( count < tries && bash( p, power, silent ).success ) {
3765 count++;
3766 }
3767}
@ success
Definition: behavior.h:20

References bash(), detail::count(), silent, and behavior::success.

◆ board_vehicle()

void map::board_vehicle ( const tripoint p,
player pl 
)

Definition at line 1114 of file map.cpp.

1115{
1116 if( p == nullptr ) {
1117 debugmsg( "map::board_vehicle: null player" );
1118 return;
1119 }
1120
1121 const std::optional<vpart_reference> vp = veh_at( pos ).part_with_feature( VPFLAG_BOARDABLE,
1122 true );
1123 if( !vp ) {
1124 if( p->grab_point.x == 0 && p->grab_point.y == 0 ) {
1125 debugmsg( "map::board_vehicle: vehicle not found" );
1126 }
1127 return;
1128 }
1129 if( vp->part().has_flag( vehicle_part::passenger_flag ) ) {
1130 player *psg = vp->vehicle().get_passenger( vp->part_index() );
1131 debugmsg( "map::board_vehicle: passenger (%s) is already there",
1132 psg ? psg->name : "<null>" );
1133 unboard_vehicle( pos );
1134 }
1135 vp->part().set_flag( vehicle_part::passenger_flag );
1136 vp->part().passenger_id = p->getID();
1137 vp->vehicle().invalidate_mass();
1138
1139 p->setpos( pos );
1140 p->in_vehicle = true;
1141 if( p->is_avatar() ) {
1142 g->update_map( g->u );
1143 }
1144}
std::string name
Definition: character.h:1566
void unboard_vehicle(const vpart_reference &, Character *passenger, bool dead_passenger=false)
Definition: map.cpp:1146
std::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2483
Definition: player.h:84
@ VPFLAG_BOARDABLE
Definition: veh_type.h:39

References debugmsg, g, Character::getID(), player::grab_point, Character::in_vehicle, Creature::is_avatar(), Character::name, optional_vpart_position::part_with_feature(), vehicle_part::passenger_flag, wrapped_vehicle::pos, Character::setpos(), unboard_vehicle(), veh_at(), VPFLAG_BOARDABLE, tripoint::x, and tripoint::y.

Referenced by debug_menu::debug(), game::phasing_move(), game::place_player(), game::swap_critters(), and avatar_action::swim().

◆ build_floor_cache()

bool map::build_floor_cache ( int  zlev)

Definition at line 8148 of file map.cpp.

8149{
8150 auto &ch = get_cache( zlev );
8151 if( !ch.floor_cache_dirty ) {
8152 return false;
8153 }
8154
8155 auto &floor_cache = ch.floor_cache;
8156 std::uninitialized_fill_n(
8157 &floor_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), true );
8158
8159 bool lowest_z_lev = zlev <= -OVERMAP_DEPTH;
8160 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8161 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8162 const submap *cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8163 const submap *below_submap = !lowest_z_lev ? get_submap_at_grid( { smx, smy, zlev - 1 } ) : nullptr;
8164
8165 if( cur_submap == nullptr ) {
8166 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy, zlev );
8167 continue;
8168 }
8169 if( !lowest_z_lev && below_submap == nullptr ) {
8170 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy,
8171 zlev - 1 );
8172 continue;
8173 }
8174
8175 for( int sx = 0; sx < SEEX; ++sx ) {
8176 for( int sy = 0; sy < SEEY; ++sy ) {
8177 point sp( sx, sy );
8178 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8179 if( terrain.has_flag( TFLAG_NO_FLOOR ) ) {
8180 if( below_submap && ( below_submap->get_furn( sp ).obj().has_flag( TFLAG_SUN_ROOF_ABOVE ) ) ) {
8181 continue;
8182 }
8183 const int x = sx + smx * SEEX;
8184 const int y = sy + smy * SEEY;
8185 floor_cache[x][y] = false;
8186 }
8187 }
8188 }
8189 }
8190 }
8191
8192 ch.floor_cache_dirty = false;
8193 return zlevels;
8194}
@ TFLAG_SUN_ROOF_ABOVE
Definition: mapdata.h:323
@ TFLAG_NO_FLOOR
Definition: mapdata.h:311
static const int sx[4]
Definition: tileray.cpp:10
static const int sy[4]
Definition: tileray.cpp:11

References debugmsg, get_cache(), get_submap_at_grid(), submap::get_ter(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, int_id< T >::obj(), OVERMAP_DEPTH, SEEX, SEEY, sx, sy, terrain, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, and zlevels.

Referenced by build_floor_caches(), and build_map_cache().

◆ build_floor_caches()

void map::build_floor_caches ( )

Definition at line 8196 of file map.cpp.

8197{
8198 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
8199 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
8200 for( int z = minz; z <= maxz; z++ ) {
8201 build_floor_cache( z );
8202 }
8203}
bool build_floor_cache(int zlev)
Definition: map.cpp:8148

References abs_sub, build_floor_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ build_map_cache()

void map::build_map_cache ( int  zlev,
bool  skip_lightmap = false 
)

Definition at line 8362 of file map.cpp.

8363{
8364 const int minz = zlevels ? -OVERMAP_DEPTH : zlev;
8365 const int maxz = zlevels ? OVERMAP_HEIGHT : zlev;
8366 bool seen_cache_dirty = false;
8367 for( int z = minz; z <= maxz; z++ ) {
8368 // trigger FOV recalculation only when there is a change on the player's level or if fov_3d is enabled
8369 const bool affects_seen_cache = z == zlev || fov_3d;
8373 seen_cache_dirty |= ( build_floor_cache( z ) && affects_seen_cache );
8374 seen_cache_dirty |= get_cache( z ).seen_cache_dirty && affects_seen_cache;
8375 diagonal_blocks fill = {false, false};
8376 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obscured_cache[0][0] ), MAPSIZE_X * MAPSIZE_Y,
8377 fill );
8378 std::uninitialized_fill_n( &( get_cache( z ).vehicle_obstructed_cache[0][0] ),
8380 }
8381 // needs a separate pass as it changes the caches on neighbour z-levels (e.g. floor_cache);
8382 // otherwise such changes might be overwritten by main cache-building logic
8383 for( int z = minz; z <= maxz; z++ ) {
8384 do_vehicle_caching( z );
8385 }
8386
8388
8389 if( seen_cache_dirty ) {
8390 skew_vision_cache.clear();
8391 }
8392 // Initial value is illegal player position.
8393 const tripoint &p = g->u.pos();
8394 static tripoint player_prev_pos;
8395 if( seen_cache_dirty || player_prev_pos != p ) {
8396 build_seen_cache( p, zlev );
8397 player_prev_pos = p;
8398 }
8399 if( !skip_lightmap ) {
8400 generate_lightmap( zlev );
8401 }
8402}
bool fov_3d
3D FoV enabled/disabled.
void build_outside_cache(int zlev)
Definition: map.cpp:8041
void update_suspension_cache(const int &z)
Definition: map.cpp:8205
void do_vehicle_caching(int z)
Definition: map.cpp:8345
void build_seen_cache(const tripoint &origin, int target_z)
Calculates the Field Of View for the provided map from the given x, y coordinates.
Definition: lightmap.cpp:1592
lru_cache< point, char > skew_vision_cache
Cache of coordinate pairs recently checked for visibility.
Definition: map.h:1984
bool build_transparency_cache(int zlev)
Definition: lightmap.cpp:105
void generate_lightmap(int zlev)
Definition: lightmap.cpp:436
bool build_vision_transparency_cache(const Character &player)
Definition: lightmap.cpp:204
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t< Char > &fill)
bool seen_cache_dirty
Definition: map.h:309

References build_floor_cache(), build_outside_cache(), build_seen_cache(), build_transparency_cache(), build_vision_transparency_cache(), do_vehicle_caching(), detail::fill(), fov_3d, g, generate_lightmap(), get_cache(), get_player_character(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::seen_cache_dirty, skew_vision_cache, update_suspension_cache(), and zlevels.

Referenced by game::do_turn(), game::draw(), game::look_around(), start_location::place_player(), game::start_game(), and game::update_map().

◆ build_obstacle_cache()

void map::build_obstacle_cache ( const tripoint start,
const tripoint end,
float(&)  obstacle_cache[MAPSIZE_X][MAPSIZE_Y] 
)

Definition at line 8095 of file map.cpp.

8097{
8098 const point min_submap{ std::max( 0, start.x / SEEX ), std::max( 0, start.y / SEEY ) };
8099 const point max_submap{
8100 std::min( my_MAPSIZE - 1, end.x / SEEX ), std::min( my_MAPSIZE - 1, end.y / SEEY ) };
8101 // Find and cache all the map obstacles.
8102 // For now setting obstacles to be extremely dense and fill their squares.
8103 // In future, scale effective obstacle density by the thickness of the obstacle.
8104 // Also consider modelling partial obstacles.
8105 // TODO: Support z-levels.
8106 for( int smx = min_submap.x; smx <= max_submap.x; ++smx ) {
8107 for( int smy = min_submap.y; smy <= max_submap.y; ++smy ) {
8108 const auto cur_submap = get_submap_at_grid( { smx, smy, start.z } );
8109
8110 // TODO: Init indices to prevent iterating over unused submap sections.
8111 for( int sx = 0; sx < SEEX; ++sx ) {
8112 for( int sy = 0; sy < SEEY; ++sy ) {
8113 const point sp( sx, sy );
8114 int ter_move = cur_submap->get_ter( sp ).obj().movecost;
8115 int furn_move = cur_submap->get_furn( sp ).obj().movecost;
8116 const int x = sx + smx * SEEX;
8117 const int y = sy + smy * SEEY;
8118 if( ter_move == 0 || furn_move < 0 || ter_move + furn_move == 0 ) {
8119 obstacle_cache[x][y] = 1000.0f;
8120 } else {
8121 obstacle_cache[x][y] = 0.0f;
8122 }
8123 }
8124 }
8125 }
8126 }
8127 VehicleList vehs = get_vehicles( start, end );
8128 const inclusive_cuboid<tripoint> bounds( start, end );
8129 // Cache all the vehicle stuff in one loop
8130 for( auto &v : vehs ) {
8131 for( const vpart_reference &vp : v.v->get_all_parts() ) {
8132 tripoint p = v.pos + vp.part().precalc[0];
8133 if( p.z != start.z ) {
8134 break;
8135 }
8136 if( !bounds.contains( p ) ) {
8137 continue;
8138 }
8139
8140 if( vp.obstacle_at_part() ) {
8141 obstacle_cache[p.x][p.y] = 1000.0f;
8142 }
8143 }
8144 }
8145
8146}
VehicleList get_vehicles()
Definition: map.cpp:297
std::vector< wrapped_vehicle > VehicleList
Definition: map.h:85

References inclusive_cuboid< Tripoint, >::contains(), get_submap_at_grid(), get_vehicles(), my_MAPSIZE, SEEX, SEEY, sx, sy, tripoint::x, tripoint::y, and tripoint::z.

◆ build_outside_cache()

void map::build_outside_cache ( int  zlev)

Definition at line 8041 of file map.cpp.

8042{
8043 auto &ch = get_cache( zlev );
8044 if( !ch.outside_cache_dirty ) {
8045 return;
8046 }
8047
8048 // Make a bigger cache to avoid bounds checking
8049 // We will later copy it to our regular cache
8050 const size_t padded_w = ( MAPSIZE_X ) + 2;
8051 const size_t padded_h = ( MAPSIZE_Y ) + 2;
8052 bool padded_cache[padded_w][padded_h];
8053
8054 auto &outside_cache = ch.outside_cache;
8055 if( zlev < 0 ) {
8056 std::uninitialized_fill_n(
8057 &outside_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), false );
8058 return;
8059 }
8060
8061 std::uninitialized_fill_n(
8062 &padded_cache[0][0], padded_w * padded_h, true );
8063
8064 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8065 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8066 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8067
8068 for( int sx = 0; sx < SEEX; ++sx ) {
8069 for( int sy = 0; sy < SEEY; ++sy ) {
8070 point sp( sx, sy );
8071 if( cur_submap->get_ter( sp ).obj().has_flag( TFLAG_INDOORS ) ||
8072 cur_submap->get_furn( sp ).obj().has_flag( TFLAG_INDOORS ) ) {
8073 const int x = sx + smx * SEEX;
8074 const int y = sy + smy * SEEY;
8075 // Add 1 to both coordinates, because we're operating on the padded cache
8076 for( int dx = 0; dx <= 2; dx++ ) {
8077 for( int dy = 0; dy <= 2; dy++ ) {
8078 padded_cache[x + dx][y + dy] = false;
8079 }
8080 }
8081 }
8082 }
8083 }
8084 }
8085 }
8086
8087 // Copy the padded cache back to the proper one, but with no padding
8088 for( int x = 0; x < SEEX * my_MAPSIZE; x++ ) {
8089 std::copy_n( &padded_cache[x + 1][1], SEEX * my_MAPSIZE, &outside_cache[x][0] );
8090 }
8091
8092 ch.outside_cache_dirty = false;
8093}

References get_cache(), get_submap_at_grid(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, sx, sy, and TFLAG_INDOORS.

Referenced by build_map_cache(), start_location::burn(), and start_location::prepare_map().

◆ build_seen_cache()

void map::build_seen_cache ( const tripoint origin,
int  target_z 
)
protected

Calculates the Field Of View for the provided map from the given x, y coordinates.

Returns a lightmap for a result where the values represent a percentage of fully lit.

A value equal to or below 0 means that cell is not in the field of view, whereas a value equal to or above 1 means that cell is in the field of view.

Parameters
originthe starting location
target_zZ-level to draw light map on

Definition at line 1592 of file lightmap.cpp.

1593{
1594 auto &map_cache = get_cache( target_z );
1595 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1596 float ( &seen_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.seen_cache;
1597 float ( &camera_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.camera_cache;
1598 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1599
1600 constexpr float light_transparency_solid = LIGHT_TRANSPARENCY_SOLID;
1601 constexpr int map_dimensions = MAPSIZE_X * MAPSIZE_Y;
1602 std::uninitialized_fill_n(
1603 &camera_cache[0][0], map_dimensions, light_transparency_solid );
1604
1605 float vision_restore_cache [9] = {0};
1606 bool blocked_restore_cache[8] = {false};
1607
1608 if( origin.z == target_z ) {
1609 apply_vision_transparency_cache( get_player_character().pos(), target_z, vision_restore_cache,
1610 blocked_restore_cache );
1611 }
1612
1613 if( !fov_3d ) {
1614 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1615 auto &cur_cache = get_cache( z );
1616 if( z == target_z || cur_cache.seen_cache_dirty ) {
1617 std::uninitialized_fill_n(
1618 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1619 cur_cache.seen_cache_dirty = false;
1620 }
1621
1622 if( z == target_z ) {
1623 seen_cache[origin.x][origin.y] = VISIBILITY_FULL;
1625 ( seen_cache, transparency_cache, blocked_cache, origin.xy(), 0 );
1626 }
1627 }
1628 } else {
1629 // Cache the caches (pointers to them)
1630 array_of_grids_of<const float> transparency_caches;
1631 array_of_grids_of<float> seen_caches;
1632 array_of_grids_of<const bool> floor_caches;
1634 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1635 auto &cur_cache = get_cache( z );
1636 transparency_caches[z + OVERMAP_DEPTH] = &cur_cache.transparency_cache;
1637 seen_caches[z + OVERMAP_DEPTH] = &cur_cache.seen_cache;
1638 floor_caches[z + OVERMAP_DEPTH] = &cur_cache.floor_cache;
1639 blocked_caches[z + OVERMAP_DEPTH] = &cur_cache.vehicle_obscured_cache;
1640 std::uninitialized_fill_n(
1641 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1642 cur_cache.seen_cache_dirty = false;
1643 }
1644 if( origin.z == target_z ) {
1646 }
1648 seen_caches, transparency_caches, floor_caches, blocked_caches, origin, 0, 1.0 );
1649 }
1650
1651 if( origin.z == target_z ) {
1652 restore_vision_transparency_cache( get_player_character().pos(), target_z, vision_restore_cache,
1653 blocked_restore_cache );
1654 }
1655
1657 if( !vp ) {
1658 return;
1659 }
1660 vehicle *const veh = &vp->vehicle();
1661
1662 // We're inside a vehicle. Do mirror calculations.
1663 std::vector<int> mirrors;
1664 // Do all the sight checks first to prevent fake multiple reflection
1665 // from happening due to mirrors becoming visible due to processing order.
1666 // Cameras are also handled here, so that we only need to get through all vehicle parts once
1667 int cam_control = -1;
1668 for( const vpart_reference &vp : veh->get_avail_parts( VPFLAG_EXTENDS_VISION ) ) {
1669 const tripoint mirror_pos = vp.pos();
1670 // We can utilize the current state of the seen cache to determine
1671 // if the player can see the mirror from their position.
1672 if( !vp.info().has_flag( "CAMERA" ) &&
1673 seen_cache[mirror_pos.x][mirror_pos.y] < LIGHT_TRANSPARENCY_SOLID + 0.1 ) {
1674 continue;
1675 } else if( !vp.info().has_flag( "CAMERA_CONTROL" ) ) {
1676 mirrors.emplace_back( static_cast<int>( vp.part_index() ) );
1677 } else {
1678 if( square_dist( origin, mirror_pos ) <= 1 && veh->camera_on ) {
1679 cam_control = static_cast<int>( vp.part_index() );
1680 }
1681 }
1682 }
1683
1684 for( int mirror : mirrors ) {
1685 bool is_camera = veh->part_info( mirror ).has_flag( "CAMERA" );
1686 if( is_camera && cam_control < 0 ) {
1687 continue; // Player not at camera control, so cameras don't work
1688 }
1689
1690 const tripoint mirror_pos = veh->global_part_pos3( mirror );
1691
1692 // Determine how far the light has already traveled so mirrors
1693 // don't cheat the light distance falloff.
1694 int offsetDistance;
1695 if( !is_camera ) {
1696 offsetDistance = rl_dist( origin, mirror_pos );
1697 } else {
1698 offsetDistance = 60 - veh->part_info( mirror ).bonus *
1699 veh->part( mirror ).hp() / veh->part_info( mirror ).durability;
1700 camera_cache[mirror_pos.x][mirror_pos.y] = LIGHT_TRANSPARENCY_OPEN_AIR;
1701 }
1702
1703 // TODO: Factor in the mirror facing and only cast in the
1704 // directions the player's line of sight reflects to.
1705 //
1706 // The naive solution of making the mirrors act like a second player
1707 // at an offset appears to give reasonable results though.
1709 (
1710 camera_cache, transparency_cache, blocked_cache, mirror_pos.xy(), offsetDistance );
1711 }
1712}
void restore_vision_transparency_cache(const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
Definition: lightmap.cpp:1506
void apply_vision_transparency_cache(const tripoint &center, int target_z, float(&vision_restore_cache)[9], bool(&blocked_restore_cache)[8])
Definition: lightmap.cpp:1467
vehicle_part_with_feature_range< std::string > get_avail_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are available: not broke...
Definition: vehicle.cpp:2716
bool camera_on
Definition: vehicle.h:1728
const vpart_info & part_info(int index, bool include_removed=false) const
Definition: vehicle.cpp:1139
int bonus
seatbelt (str), muffler (%), horn (vol), light (intensity), recharing (power)
Definition: veh_type.h:269
bool has_flag(const std::string &flag) const
Definition: veh_type.h:336
int durability
Maximum damage part can sustain before being destroyed.
Definition: veh_type.h:173
template void cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(const array_of_grids_of< float > &output_caches, const array_of_grids_of< const float > &input_arrays, const array_of_grids_of< const bool > &floor_caches, const array_of_grids_of< const diagonal_blocks > &blocked_caches, const tripoint &origin, int offset_distance, float numerator)
template void castLightAllWithLookup< float, float, sight_calc, sight_check, update_light, accumulate_transparency, sight_from_lookup >(float(&output_cache)[MAPSIZE_X][MAPSIZE_Y], const float(&input_array)[MAPSIZE_X][MAPSIZE_Y], const diagonal_blocks(&blocked_array)[MAPSIZE_X][MAPSIZE_Y], const point &offset, int offsetDistance, float numerator)
static constexpr float VISIBILITY_FULL
Definition: lightmap.h:39
std::array< T(*)[MAPSIZE_X][MAPSIZE_Y], OVERMAP_LAYERS > array_of_grids_of
int hp() const
current part health with range [0,durability]
@ VPFLAG_EXTENDS_VISION
Definition: veh_type.h:68

References apply_vision_transparency_cache(), vpart_info::bonus, vehicle::camera_on, cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(), castLightAllWithLookup< float, float, sight_calc, sight_check, update_light, accumulate_transparency, sight_from_lookup >(), vpart_info::durability, fov_3d, vehicle::get_avail_parts(), get_cache(), get_player_character(), vehicle::global_part_pos3(), vpart_info::has_flag(), vehicle_part::hp(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::part(), vehicle::part_info(), restore_vision_transparency_cache(), rl_dist(), level_cache::seen_cache, square_dist(), veh_at(), VISIBILITY_FULL, VPFLAG_EXTENDS_VISION, tripoint::x, tripoint::xy(), and tripoint::y.

Referenced by build_map_cache().

◆ build_sunlight_cache()

void map::build_sunlight_cache ( int  pzlev)
protected

Definition at line 285 of file lightmap.cpp.

286{
287 const int zlev_min = zlevels ? -OVERMAP_DEPTH : pzlev;
288 // Start at the topmost populated zlevel to avoid unnecessary raycasting
289 // Plus one zlevel to prevent clipping inside structures
290 const int zlev_max = zlevels
292 std::min( OVERMAP_HEIGHT, pzlev + 1 ),
294 : pzlev;
295
296 // true if all previous z-levels are fully transparent to light (no floors, transparency >= air)
297 bool fully_outside = true;
298
299 // true if no light reaches this level, i.e. there were no lit tiles on the above level (light level <= inside_light_level)
300 bool fully_inside = false;
301
302 // fully_outside and fully_inside define following states:
303 // initially: fully_outside=true, fully_inside=false (fast fill)
304 // ↓
305 // when first obstacles occur: fully_outside=false, fully_inside=false (slow quadrant logic)
306 // ↓
307 // when fully below ground: fully_outside=false, fully_inside=true (fast fill)
308
309 // Iterate top to bottom because sunlight cache needs to construct in that order.
310 for( int zlev = zlev_max; zlev >= zlev_min; zlev-- ) {
311
312 level_cache &map_cache = get_cache( zlev );
313 auto &lm = map_cache.lm;
314 // Grab illumination at ground level.
315 const float outside_light_level = g->natural_light_level( 0 );
316 // TODO: if zlev < 0 is open to sunlight, this won't calculate correct light, but neither does g->natural_light_level()
317 const float inside_light_level = ( zlev >= 0 && outside_light_level > LIGHT_SOURCE_BRIGHT ) ?
319 // Handling when z-levels are disabled is based on whether a tile is considered "outside".
320 if( !zlevels ) {
321 const auto &outside_cache = map_cache.outside_cache;
322 for( int x = 0; x < MAPSIZE_X; x++ ) {
323 for( int y = 0; y < MAPSIZE_Y; y++ ) {
324 if( outside_cache[x][y] ) {
325 lm[x][y].fill( outside_light_level );
326 } else {
327 lm[x][y].fill( inside_light_level );
328 }
329 }
330 }
331 continue;
332 }
333
334 // all light was blocked before
335 if( fully_inside ) {
336 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
337 continue;
338 }
339
340 // If there were no obstacles before this level, just apply weather illumination since there's no opportunity
341 // for light to be blocked.
342 if( fully_outside ) {
343 //fill with full light
344 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( outside_light_level ) );
345
346 const auto &this_floor_cache = map_cache.floor_cache;
347 const auto &this_transparency_cache = map_cache.transparency_cache;
348 fully_inside = true; // recalculate
349
350 for( int x = 0; x < MAPSIZE_X; ++x ) {
351 for( int y = 0; y < MAPSIZE_Y; ++y ) {
352 // && semantics below is important, we want to skip the evaluation if possible, do not replace with &=
353
354 // fully_outside stays true if tile is transparent and there is no floor
355 fully_outside = fully_outside && this_transparency_cache[x][y] >= LIGHT_TRANSPARENCY_OPEN_AIR
356 && !this_floor_cache[x][y];
357 // fully_inside stays true if tile is opaque OR there is floor
358 fully_inside = fully_inside && ( this_transparency_cache[x][y] <= LIGHT_TRANSPARENCY_SOLID ||
359 this_floor_cache[x][y] );
360 }
361 }
362 continue;
363 }
364
365 // Replace this with a calculated shift based on time of day and date.
366 // At first compress the angle such that it takes no more than one tile of shift per level.
367 // To exceed that, we'll have to handle casting light from the side instead of the top.
368 point offset;
369 const level_cache &prev_map_cache = get_cache_ref( zlev + 1 );
370 const auto &prev_lm = prev_map_cache.lm;
371 const auto &prev_transparency_cache = prev_map_cache.transparency_cache;
372 const auto &prev_floor_cache = prev_map_cache.floor_cache;
373 const auto &outside_cache = map_cache.outside_cache;
374 const float sight_penalty = get_weather().weather_id->sight_penalty;
375 // TODO: Replace these with a lookup inside the four_quadrants class.
376 constexpr std::array<point, 5> cardinals = {
378 };
379 constexpr std::array<std::array<quadrant, 2>, 5> dir_quadrants = {{
385 }
386 };
387
388 fully_inside = true; // recalculate
389
390 // Fall back to minimal light level if we don't find anything.
391 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
392
393 for( int x = 0; x < MAPSIZE_X; ++x ) {
394 for( int y = 0; y < MAPSIZE_Y; ++y ) {
395 // Check center, then four adjacent cardinals.
396 for( int i = 0; i < 5; ++i ) {
397 int prev_x = x + offset.x + cardinals[i].x;
398 int prev_y = y + offset.y + cardinals[i].y;
399 bool inbounds = prev_x >= 0 && prev_x < MAPSIZE_X &&
400 prev_y >= 0 && prev_y < MAPSIZE_Y;
401
402 if( !inbounds ) {
403 continue;
404 }
405
406 float prev_light_max;
407 float prev_transparency = prev_transparency_cache[prev_x][prev_y];
408 // This is pretty gross, this cancels out the per-tile transparency effect
409 // derived from weather.
410 if( outside_cache[x][y] ) {
411 prev_transparency /= sight_penalty;
412 }
413
414 if( prev_transparency > LIGHT_TRANSPARENCY_SOLID &&
415 !prev_floor_cache[prev_x][prev_y] &&
416 ( prev_light_max = prev_lm[prev_x][prev_y].max() ) > 0.0 ) {
417 const float light_level = clamp( prev_light_max * LIGHT_TRANSPARENCY_OPEN_AIR / prev_transparency,
418 inside_light_level, prev_light_max );
419
420 if( i == 0 ) {
421 lm[x][y].fill( light_level );
422 fully_inside &= light_level <= inside_light_level;
423 break;
424 } else {
425 fully_inside &= light_level <= inside_light_level;
426 lm[x][y][dir_quadrants[i][0]] = light_level;
427 lm[x][y][dir_quadrants[i][1]] = light_level;
428 }
429 }
430 }
431 }
432 }
433 }
434}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:149
int calc_max_populated_zlev()
Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.
Definition: map.cpp:9145
weather_type_id weather_id
Definition: weather.h:193
weather_manager & get_weather()
Definition: weather.cpp:64
static constexpr float LIGHT_AMBIENT_DIM
Definition: lightmap.h:16
bool floor_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:328
bool outside_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:322
float sight_penalty
Definition: weather_type.h:111

References calc_max_populated_zlev(), clamp(), level_cache::floor_cache, g, get_cache(), get_cache_ref(), get_weather(), inbounds(), LIGHT_AMBIENT_DIM, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, level_cache::lm, MAPSIZE_X, MAPSIZE_Y, NE, NW, level_cache::outside_cache, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_east, point_north, point_south, point_west, point_zero, SE, weather_type::sight_penalty, SW, level_cache::transparency_cache, weather_manager::weather_id, point::x, point::y, and zlevels.

Referenced by generate_lightmap().

◆ build_transparency_cache()

bool map::build_transparency_cache ( int  zlev)
protected

Definition at line 105 of file lightmap.cpp.

106{
107 auto &map_cache = get_cache( zlev );
108 auto &transparency_cache = map_cache.transparency_cache;
109 auto &outside_cache = map_cache.outside_cache;
110
111 if( map_cache.transparency_cache_dirty.none() ) {
112 return false;
113 }
114
115 std::set<tripoint> vehicles_processed;
116
117 // if true, all submaps are invalid (can use batch init)
118 bool rebuild_all = map_cache.transparency_cache_dirty.all();
119
120 if( rebuild_all ) {
121 // Default to just barely not transparent.
122 std::uninitialized_fill_n( &transparency_cache[0][0], MAPSIZE_X * MAPSIZE_Y,
123 static_cast<float>( LIGHT_TRANSPARENCY_OPEN_AIR ) );
124 }
125
126 const float sight_penalty = get_weather().weather_id->sight_penalty;
127
128 if( sight_penalty != 1.0f &&
129 LIGHT_TRANSPARENCY_OPEN_AIR * sight_penalty != weather_transparency_lookup.transparency ) {
131 }
132
133 // Traverse the submaps in order
134 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
135 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
136 const auto cur_submap = get_submap_at_grid( {smx, smy, zlev} );
137
138 const point sm_offset = sm_to_ms_copy( point( smx, smy ) );
139
140 if( !rebuild_all && !map_cache.transparency_cache_dirty[smx * MAPSIZE + smy] ) {
141 continue;
142 }
143
144 // calculates transparency of a single tile
145 // x,y - coords in map local coords
146 auto calc_transp = [&]( point p ) {
147 const point sp = p - sm_offset;
148 float value = LIGHT_TRANSPARENCY_OPEN_AIR;
149
150 if( !( cur_submap->get_ter( sp ).obj().transparent &&
151 cur_submap->get_furn( sp ).obj().transparent ) ) {
153 }
154 if( outside_cache[p.x][p.y] ) {
155 // FIXME: Places inside vehicles haven't been marked as
156 // inside yet so this is incorrectly penalising for
157 // weather in vehicles.
158 value *= sight_penalty;
159 }
160 for( const auto &fld : cur_submap->get_field( sp ) ) {
161 const field_entry &cur = fld.second;
162 if( cur.is_transparent() ) {
163 continue;
164 }
165 // Fields are either transparent or not, however we want some to be translucent
166 value = value * cur.translucency();
167 }
168 // TODO: [lightmap] Have glass reduce light as well
169 return value;
170 };
171
172 if( cur_submap->is_uniform ) {
173 float value = calc_transp( sm_offset );
174 // if rebuild_all==true all values were already set to LIGHT_TRANSPARENCY_OPEN_AIR
175 if( !rebuild_all || value != LIGHT_TRANSPARENCY_OPEN_AIR ) {
176 for( int sx = 0; sx < SEEX; ++sx ) {
177 // init all sy indices in one go
178 std::uninitialized_fill_n( &transparency_cache[sm_offset.x + sx][sm_offset.y], SEEY, value );
179 }
180 }
181 } else {
182 for( int sx = 0; sx < SEEX; ++sx ) {
183 const int x = sx + sm_offset.x;
184 for( int sy = 0; sy < SEEY; ++sy ) {
185 const int y = sy + sm_offset.y;
186 transparency_cache[x][y] = calc_transp( { x, y } );
187
188 //Nudge things towards fast paths
189 if( std::fabs( transparency_cache[x][y] - openair_transparency_lookup.transparency ) <= 0.0001 ) {
190 transparency_cache[x][y] = openair_transparency_lookup.transparency;
191 } else if( std::fabs( transparency_cache[x][y] - weather_transparency_lookup.transparency ) <=
192 0.0001 ) {
193 transparency_cache[x][y] = weather_transparency_lookup.transparency;
194 }
195 }
196 }
197 }
198 }
199 }
200 map_cache.transparency_cache_dirty.reset();
201 return true;
202}
An active or passive effect existing on a tile.
Definition: field.h:20
bool is_transparent() const
Definition: field.cpp:84
float translucency() const
Definition: field.cpp:79
transparency_exp_lookup< 90 > weather_transparency_lookup(LIGHT_TRANSPARENCY_OPEN_AIR *1.1)
const transparency_exp_lookup< 90 > openair_transparency_lookup(LIGHT_TRANSPARENCY_OPEN_AIR)
quantity< V, U > fabs(quantity< V, U > q)
Definition: units_def.h:136

References units::fabs(), get_cache(), get_submap_at_grid(), get_weather(), field_entry::is_transparent(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, openair_transparency_lookup, SEEX, SEEY, weather_type::sight_penalty, sm_to_ms_copy(), sx, sy, field_entry::translucency(), weather_manager::weather_id, and weather_transparency_lookup.

Referenced by build_map_cache().

◆ build_vision_transparency_cache()

bool map::build_vision_transparency_cache ( const Character player)
protected

Definition at line 204 of file lightmap.cpp.

205{
206 const tripoint &p = player.pos();
207
208 bool dirty = false;
209
211
212 const auto check_vehicle_coverage = []( const vehicle * veh, point p ) -> bool {
213 return veh->obstacle_at_position( p ) == -1 && ( veh->part_with_feature( p, "AISLE", true ) != -1 || veh->part_with_feature( p, "PROTRUSION", true ) != -1 );
214 };
215
216 const optional_vpart_position player_vp = veh_at( p );
217
218 point player_mount;
219 if( player_vp ) {
220 player_mount = player_vp->vehicle().tripoint_to_mount( p );
221 }
222
223 int i = 0;
224 for( point adjacent : eight_adjacent_offsets ) {
226
227 // If we're crouching behind an obstacle, we can't see past it.
228 if( coverage( adjacent + p ) >= 30 ) {
229 dirty = true;
231 } else {
233 adjacent ) != four_diagonal_offsets.end() ) {
234 const optional_vpart_position adjacent_vp = veh_at( p + adjacent );
235
236 point adjacent_mount;
237 if( adjacent_vp ) {
238 adjacent_mount = adjacent_vp->vehicle().tripoint_to_mount( p );
239 }
240
241 if( ( player_vp &&
242 !player_vp->vehicle().check_rotated_intervening( player_mount,
243 player_vp->vehicle().tripoint_to_mount( p + adjacent ),
244 check_vehicle_coverage ) )
245 || ( adjacent_vp && ( !player_vp || &( player_vp->vehicle() ) != &( adjacent_vp->vehicle() ) ) &&
246 !adjacent_vp->vehicle().check_rotated_intervening( adjacent_vp->vehicle().tripoint_to_mount(
247 p ), adjacent_vp->vehicle().tripoint_to_mount( p + adjacent ),
248 check_vehicle_coverage ) ) ) {
249 dirty = true;
251 }
252 }
253 }
254
255 i++;
256 }
257 } else {
258 std::fill_n( &vision_transparency_cache[0], 8, VISION_ADJUST_NONE );
259 }
260 return dirty;
261}
@ CMM_CROUCH
Definition: character.h:111
bool movement_mode_is(character_movemode mode) const
Check against the character's current movement mode.
Definition: character.cpp:1560
int coverage(const tripoint &p) const
Returns coverage value of the tile.
Definition: map.cpp:6384
int part_with_feature(int p, const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2522
int obstacle_at_position(point pos) const
Definition: vehicle.cpp:2584
@ VISION_ADJUST_NONE
Definition: lightmap.h:77

References CMM_CROUCH, coverage(), eight_adjacent_offsets, detail::find(), four_diagonal_offsets, Character::movement_mode_is(), vehicle::obstacle_at_position(), vehicle::part_with_feature(), Character::pos(), veh_at(), VISION_ADJUST_HIDDEN, VISION_ADJUST_NONE, VISION_ADJUST_SOLID, and vision_transparency_cache.

Referenced by build_map_cache().

◆ burn_body_part()

int map::burn_body_part ( player u,
field_entry cur,
body_part  bp,
int  scale 
)
private

Definition at line 125 of file map_field.cpp.

126{
127 int total_damage = 0;
128 const int intensity = cur.get_field_intensity();
129 const int damage = rng( 1, ( scale + intensity ) / 2 );
130 // A bit ugly, but better than being annoyed by acid when in hazmat
131 if( u.get_armor_type( DT_ACID, convert_bp( bp ) ) < damage ) {
132 const dealt_damage_instance ddi = u.deal_damage( nullptr, convert_bp( bp ).id(),
133 damage_instance( DT_ACID, damage ) );
134 total_damage += ddi.total_damage();
135 }
136 // Represents acid seeping in rather than being splashed on
138 1 + intensity ) ), bp, 0 );
139 return total_damage;
140}
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8465
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6880
bool add_env_effect(const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
Gives chance to save via environmental resist, returns false if resistance was successful.
Definition: creature.cpp:1140
int get_field_intensity() const
Definition: field.cpp:121
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_corroding("corroding")
int total_damage() const
Definition: damage.cpp:180

References Creature::add_env_effect(), convert_bp(), Character::deal_damage(), DT_ACID, effect_corroding, time_duration::from_turns(), Character::get_armor_type(), field_entry::get_field_intensity(), rng(), and dealt_damage_instance::total_damage().

Referenced by player_in_field().

◆ calc_max_populated_zlev()

int map::calc_max_populated_zlev ( )
private

Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.

fills the map::max_populated_zlev and returns it

Returns
max_populated_zlev value

Definition at line 9145 of file map.cpp.

9146{
9147 // cache is filled and valid, skip recalculation
9149 return max_populated_zlev->second;
9150 }
9151
9152 // We'll assume ground level is populated
9153 int max_z = 0;
9154
9155 for( int sz = 1; sz <= OVERMAP_HEIGHT; sz++ ) {
9156 bool level_done = false;
9157 for( int sx = 0; sx < my_MAPSIZE; sx++ ) {
9158 for( int sy = 0; sy < my_MAPSIZE; sy++ ) {
9159 const submap *sm = get_submap_at_grid( tripoint( sx, sy, sz ) );
9160 if( !sm->is_uniform ) {
9161 max_z = sz;
9162 level_done = true;
9163 break;
9164 }
9165 }
9166 if( level_done ) {
9167 break;
9168 }
9169 }
9170 }
9171
9172 max_populated_zlev = std::pair<tripoint, int>( get_abs_sub(), max_z );
9173 return max_z;
9174}
std::optional< std::pair< tripoint, int > > max_populated_zlev
Definition: map.h:2003
tripoint get_abs_sub() const
return abs_sub
Definition: map.cpp:8433

References get_abs_sub(), get_submap_at_grid(), max_populated_zlev, my_MAPSIZE, OVERMAP_HEIGHT, coords::sm, sx, and sy.

Referenced by build_sunlight_cache().

◆ can_move_furniture()

bool map::can_move_furniture ( const tripoint pos,
player p = nullptr 
)
Strength determines what furniture the player can move

Definition at line 1510 of file map.cpp.

1511{
1512 if( !p ) {
1513 return false;
1514 }
1515 const furn_t &furniture_type = furn( pos ).obj();
1516 int required_str = furniture_type.move_str_req;
1517
1518 // Object can not be moved (or nothing there)
1519 if( required_str < 0 ) {
1520 return false;
1521 }
1522
1523 ///\EFFECT_STR determines what furniture the player can move
1524 int adjusted_str = p->str_cur;
1525 if( p->is_mounted() ) {
1526 auto mons = p->mounted_creature.get();
1527 if( mons->has_flag( MF_RIDEABLE_MECH ) && mons->mech_str_addition() != 0 ) {
1528 adjusted_str = mons->mech_str_addition();
1529 }
1530 }
1531 return adjusted_str >= required_str;
1532}
int str_cur
Definition: character.h:264
bool is_mounted() const
Definition: character.cpp:1083
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1617
@ MF_RIDEABLE_MECH
Definition: mtype.h:115
int move_str_req
Definition: mapdata.h:519

References furn(), Character::is_mounted(), MF_RIDEABLE_MECH, Character::mounted_creature, furn_t::move_str_req, int_id< T >::obj(), wrapped_vehicle::pos, and Character::str_cur.

◆ can_put_items() [1/2]

bool map::can_put_items ( const tripoint p) const

Definition at line 2380 of file map.cpp.

2381{
2382 if( can_put_items_ter_furn( p ) ) {
2383 return true;
2384 }
2385 const optional_vpart_position vp = veh_at( p );
2386 return static_cast<bool>( vp.part_with_feature( "CARGO", true ) );
2387}
bool can_put_items_ter_furn(const tripoint &p) const
Definition: map.cpp:2389

References can_put_items_ter_furn(), optional_vpart_position::part_with_feature(), and veh_at().

Referenced by can_put_items(), and game::place_player().

◆ can_put_items() [2/2]

bool map::can_put_items ( point  p) const
inline

Definition at line 909 of file map.h.

909 {
910 return can_put_items( tripoint( p, abs_sub.z ) );
911 }
bool can_put_items(const tripoint &p) const
Definition: map.cpp:2380

References abs_sub, can_put_items(), and tripoint::z.

◆ can_put_items_ter_furn() [1/2]

bool map::can_put_items_ter_furn ( const tripoint p) const

Definition at line 2389 of file map.cpp.

2390{
2391 return !has_flag( "NOITEM", p ) && !has_flag( "SEALED", p );
2392}

References has_flag().

Referenced by can_put_items(), and can_put_items_ter_furn().

◆ can_put_items_ter_furn() [2/2]

bool map::can_put_items_ter_furn ( point  p) const
inline

Definition at line 914 of file map.h.

914 {
916 }

References abs_sub, can_put_items_ter_furn(), and tripoint::z.

◆ can_see_trap_at()

bool map::can_see_trap_at ( const tripoint p,
const Character c 
) const

See trap::can_see, which is called for the trap here.

Definition at line 5253 of file map.cpp.

5254{
5255 return tr_at( p ).can_see( p, c );
5256}
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:5258
constexpr double c
Definition: magic.cpp:1032
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References c, trap::can_see(), and tr_at().

◆ check_and_set_seen_cache()

bool map::check_and_set_seen_cache ( const tripoint p) const

Definition at line 8959 of file map.cpp.

8960{
8961 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
8963 if( !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ] ) {
8964 memory_seen_cache.set( static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) );
8965 return true;
8966 }
8967 return false;
8968}
std::bitset< MAPSIZE_X *MAPSIZE_Y > map_memory_seen_cache
Definition: map.h:351

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by draw_maptile().

◆ check_seen_cache()

bool map::check_seen_cache ( const tripoint p) const

Definition at line 8952 of file map.cpp.

8953{
8954 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
8956 return !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ];
8957}

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

◆ check_submap_active_item_consistency()

std::vector< tripoint > map::check_submap_active_item_consistency ( )

Definition at line 4674 of file map.cpp.

4675{
4676 std::vector<tripoint> result;
4677 for( int z = -OVERMAP_DEPTH; z < OVERMAP_HEIGHT; ++z ) {
4678 for( int x = 0; x < MAPSIZE; ++x ) {
4679 for( int y = 0; y < MAPSIZE; ++y ) {
4680 tripoint p( x, y, z );
4681 submap *s = get_submap_at_grid( p );
4682 bool has_active_items = !s->active_items.get().empty();
4683 bool map_has_active_items = submaps_with_active_items.count( p + abs_sub.xy() );
4684 if( has_active_items != map_has_active_items ) {
4685 result.push_back( p + abs_sub.xy() );
4686 }
4687 }
4688 }
4689 }
4690 for( const tripoint &p : submaps_with_active_items ) {
4691 tripoint rel = p - abs_sub.xy();
4693 if( !map.contains( rel.xy() ) ) {
4694 result.push_back( p );
4695 }
4696 }
4697 return result;
4698}
std::vector< item_reference > get()
Returns a vector of all cached active item references.
Manage and cache data about a part of the map.
Definition: map.h:384

References abs_sub, submap::active_items, active_item_cache::get(), get_submap_at_grid(), map(), MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, submaps_with_active_items, and tripoint::xy().

◆ check_vehicle_zones()

bool map::check_vehicle_zones ( int  zlev)

Definition at line 989 of file map.cpp.

990{
991 for( auto veh : get_cache( zlev ).zone_vehicles ) {
992 if( veh->zones_dirty ) {
993 return true;
994 }
995 }
996 return false;
997}

References get_cache().

◆ clear_path()

bool map::clear_path ( const tripoint f,
const tripoint t,
int  range,
int  cost_min,
int  cost_max 
) const

Check whether there's a direct line of sight between F and T with the additional movecost restraints.

Checks two things:

  1. The sees() algorithm between F and T
  2. That moving over the line of sight would have a move_cost between cost_min and cost_max.

Definition at line 6535 of file map.cpp.

6537{
6538 // Ugly `if` for now
6539 if( !fov_3d && f.z != t.z ) {
6540 return false;
6541 }
6542
6543 if( f.z == t.z ) {
6544 if( ( range >= 0 && range < rl_dist( f.xy(), t.xy() ) ) ||
6545 !inbounds( t ) ) {
6546 return false; // Out of range!
6547 }
6548 bool is_clear = true;
6549 point last_point = f.xy();
6550 bresenham( f.xy(), t.xy(), 0,
6551 [this, &is_clear, cost_min, cost_max, &t, &last_point]( point new_point ) {
6552 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6553 if( new_point.x == t.x && new_point.y == t.y ) {
6554 return false;
6555 }
6556
6557 const int cost = this->move_cost( new_point );
6558 if( cost < cost_min || cost > cost_max ||
6559 obstructed_by_vehicle_rotation( tripoint( last_point, t.z ), tripoint( new_point,
6560 t.z ) ) ) {
6561 is_clear = false;
6562 return false;
6563 }
6564
6565 last_point = new_point;
6566 return true;
6567 } );
6568 return is_clear;
6569 }
6570
6571 if( ( range >= 0 && range < rl_dist( f, t ) ) ||
6572 !inbounds( t ) ) {
6573 return false; // Out of range!
6574 }
6575 bool is_clear = true;
6576 tripoint last_point = f;
6577 bresenham( f, t, 0, 0,
6578 [this, &is_clear, cost_min, cost_max, t, &last_point]( const tripoint & new_point ) {
6579 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6580 if( new_point == t ) {
6581 return false;
6582 }
6583
6584 // We have to check a weird case where the move is both vertical and horizontal
6585 if( new_point.z == last_point.z ) {
6586 const int cost = move_cost( new_point );
6587 if( cost < cost_min || cost > cost_max ||
6588 obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6589 is_clear = false;
6590 return false;
6591 }
6592 } else {
6593 bool this_clear = false;
6594 const int max_z = std::max( new_point.z, last_point.z );
6595 if( !has_floor_or_support( {new_point.xy(), max_z} ) ) {
6596 const int cost = move_cost( {new_point.xy(), last_point.z} );
6597 if( cost > cost_min && cost < cost_max &&
6598 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6599 this_clear = true;
6600 }
6601 }
6602
6603 if( !this_clear && has_floor_or_support( {last_point.xy(), max_z} ) ) {
6604 const int cost = move_cost( {last_point.xy(), new_point.z} );
6605 if( cost > cost_min && cost < cost_max &&
6606 !obstructed_by_vehicle_rotation( last_point, new_point ) ) {
6607 this_clear = true;
6608 }
6609 }
6610
6611 if( !this_clear ) {
6612 is_clear = false;
6613 return false;
6614 }
6615 }
6616
6617 last_point = new_point;
6618 return true;
6619 } );
6620 return is_clear;
6621}
bool has_floor_or_support(const tripoint &p) const
Definition: map.cpp:2121
int move_cost(const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
Calculate the cost to move past the tile at p.
Definition: map.cpp:1845
void bresenham(point p1, point p2, int t, const std::function< bool(point)> &interact)
The actual Bresenham algorithm in 2D and 3D, everything else should call these and pass in an interac...
Definition: line.cpp:24

References bresenham(), fov_3d, inbounds(), obstructed_by_vehicle_rotation(), range, rl_dist(), tripoint::xy(), and tripoint::z.

Referenced by process_fields_in_submap(), and game::start_game().

◆ clear_spawns()

void map::clear_spawns ( )

Definition at line 7864 of file map.cpp.

7865{
7866 for( auto &smap : grid ) {
7867 smap->spawns.clear();
7868 }
7869}

References grid.

Referenced by defense_game::init_map().

◆ clear_traps()

void map::clear_traps ( )

Definition at line 7871 of file map.cpp.

7872{
7873 for( auto &smap : grid ) {
7874 for( int x = 0; x < SEEX; x++ ) {
7875 for( int y = 0; y < SEEY; y++ ) {
7876 const point p( x, y );
7877 smap->set_trap( p, tr_null );
7878 }
7879 }
7880 }
7881
7882 // Forget about all trap locations.
7883 for( auto &i : traplocs ) {
7884 i.clear();
7885 }
7886}

References grid, SEEX, SEEY, tr_null, and traplocs.

Referenced by defense_game::init_map().

◆ clear_vehicle_cache()

void map::clear_vehicle_cache ( )

Definition at line 373 of file map.cpp.

374{
375 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
376 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
377 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
378 level_cache &ch = get_cache( zlev );
379 while( !ch.veh_cached_parts.empty() ) {
380 const auto part = ch.veh_cached_parts.begin();
381 const auto &p = part->first;
382 if( inbounds( p ) ) {
383 ch.veh_exists_at[p.x][p.y] = false;
384 }
385 ch.veh_cached_parts.erase( part );
386 }
387 ch.veh_in_active_range = false;
388 }
389}

References abs_sub, get_cache(), inbounds(), OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by game::place_player_overmap(), reset_vehicle_cache(), rotate(), shift(), and game::vertical_shift().

◆ clear_vehicle_list()

void map::clear_vehicle_list ( int  zlev)

Definition at line 391 of file map.cpp.

392{
393 auto &ch = get_cache( zlev );
394 ch.vehicle_list.clear();
395 ch.zone_vehicles.clear();
396
398}

References get_cache(), and last_full_vehicle_list_dirty.

Referenced by game::place_player_overmap(), rotate(), and shift().

◆ clear_vehicle_point_from_cache()

void map::clear_vehicle_point_from_cache ( vehicle veh,
const tripoint pt 
)

Definition at line 355 of file map.cpp.

356{
357 if( veh == nullptr ) {
358 debugmsg( "Tried to clear null vehicle from cache" );
359 return;
360 }
361
362 level_cache &ch = get_cache( pt.z );
363 if( inbounds( pt ) ) {
364 ch.veh_exists_at[pt.x][pt.y] = false;
365 }
366 auto it = ch.veh_cached_parts.find( pt );
367 if( it != ch.veh_cached_parts.end() && it->second.first == veh ) {
368 ch.veh_cached_parts.erase( it );
369 }
370
371}

References debugmsg, get_cache(), inbounds(), level_cache::veh_cached_parts, level_cache::veh_exists_at, tripoint::x, tripoint::y, and tripoint::z.

Referenced by veh_interact::complete_vehicle().

◆ climb_difficulty()

int map::climb_difficulty ( const tripoint p) const

Checks 3x3 block centered on p for terrain to climb.

Returns
Difficulty of climbing check from point p.

Definition at line 2034 of file map.cpp.

2035{
2036 if( p.z > OVERMAP_HEIGHT || p.z < -OVERMAP_DEPTH ) {
2037 debugmsg( "climb_difficulty on out of bounds point: %d, %d, %d", p.x, p.y, p.z );
2038 return INT_MAX;
2039 }
2040
2041 int best_difficulty = INT_MAX;
2042 int blocks_movement = 0;
2043 if( has_flag( "LADDER", p ) ) {
2044 // Really easy, but you have to stand on the tile
2045 return 1;
2046 } else if( has_flag( TFLAG_RAMP, p ) || has_flag( TFLAG_RAMP_UP, p ) ||
2047 has_flag( TFLAG_RAMP_DOWN, p ) ) {
2048 // We're on something stair-like, so halfway there already
2049 best_difficulty = 7;
2050 }
2051
2052 for( const auto &pt : points_in_radius( p, 1 ) ) {
2053 if( impassable_ter_furn( pt ) ) {
2054 // TODO: Non-hardcoded climbability
2055 best_difficulty = std::min( best_difficulty, 10 );
2056 blocks_movement++;
2057 } else if( veh_at( pt ) ) {
2058 // Vehicle tiles are quite good for climbing
2059 // TODO: Penalize spiked parts?
2060 best_difficulty = std::min( best_difficulty, 7 );
2061 }
2062
2063 if( best_difficulty > 5 && has_flag( "CLIMBABLE", pt ) ) {
2064 best_difficulty = 5;
2065 }
2066 }
2067
2068 // TODO: Make this more sensible - check opposite sides, not just movement blocker count
2069 return std::max( 0, best_difficulty - blocks_movement );
2070}
bool impassable_ter_furn(const tripoint &p) const
Definition: map.cpp:1893
@ TFLAG_RAMP_UP
Definition: mapdata.h:314
@ TFLAG_RAMP
Definition: mapdata.h:315
@ TFLAG_RAMP_DOWN
Definition: mapdata.h:313

References debugmsg, has_flag(), impassable_ter_furn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, veh_at(), tripoint::x, tripoint::y, and tripoint::z.

◆ clip_to_bounds() [1/3]

void map::clip_to_bounds ( int &  x,
int &  y 
) const

Definition at line 9088 of file map.cpp.

9089{
9090 if( x < 0 ) {
9091 x = 0;
9092 } else if( x >= SEEX * my_MAPSIZE ) {
9093 x = SEEX * my_MAPSIZE - 1;
9094 }
9095
9096 if( y < 0 ) {
9097 y = 0;
9098 } else if( y >= SEEY * my_MAPSIZE ) {
9099 y = SEEY * my_MAPSIZE - 1;
9100 }
9101}

References my_MAPSIZE, SEEX, and SEEY.

◆ clip_to_bounds() [2/3]

void map::clip_to_bounds ( int &  x,
int &  y,
int &  z 
) const

Definition at line 9103 of file map.cpp.

9104{
9105 clip_to_bounds( x, y );
9106 if( z < -OVERMAP_DEPTH ) {
9107 z = -OVERMAP_DEPTH;
9108 } else if( z > OVERMAP_HEIGHT ) {
9109 z = OVERMAP_HEIGHT;
9110 }
9111}
void clip_to_bounds(tripoint &p) const
Clips the coordinates of p to fit the map bounds.
Definition: map.cpp:9083

References clip_to_bounds(), OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ clip_to_bounds() [3/3]

void map::clip_to_bounds ( tripoint p) const

Clips the coordinates of p to fit the map bounds.

Definition at line 9083 of file map.cpp.

9084{
9085 clip_to_bounds( p.x, p.y, p.z );
9086}

References clip_to_bounds(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by MapgenRemovePartHandler::add_item_or_charges(), clip_to_bounds(), and route().

◆ close_door()

bool map::close_door ( const tripoint p,
bool  inside,
bool  check_only 
)

Definition at line 4094 of file map.cpp.

4095{
4096 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
4097 return false;
4098 }
4099
4100 const auto &ter = this->ter( p ).obj();
4101 const auto &furn = this->furn( p ).obj();
4102 if( ter.close && !furn.id ) {
4103 if( !check_only ) {
4104 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
4105 "close_door", ter.id.str() );
4106 ter_set( p, ter.close );
4107 }
4108 return true;
4109 } else if( furn.close ) {
4110 if( !check_only ) {
4111 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
4112 "close_door", furn.id.str() );
4113 furn_set( p, furn.close );
4114 }
4115 return true;
4116 }
4117 return false;
4118}
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References _, furn(), furn_set(), has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), sounds::sound(), string_id< T >::str(), ter(), and ter_set().

Referenced by doors::close_door(), and game::try_get_right_click_action().

◆ collapse_at()

void map::collapse_at ( const tripoint p,
bool  silent,
bool  was_supporting = false,
bool  destroy_pos = true 
)

Causes a collapse at p, such as from destroying a wall.

Definition at line 2961 of file map.cpp.

2963{
2964 const bool supports = was_supporting || has_flag( TFLAG_SUPPORTS_ROOF, p );
2965 const bool wall = was_supporting || has_flag( TFLAG_WALL, p );
2966 // don't bash again if the caller already bashed here
2967 if( destroy_pos ) {
2968 destroy( p, silent );
2969 crush( p );
2970 make_rubble( p );
2971 }
2972 const bool still_supports = has_flag( TFLAG_SUPPORTS_ROOF, p );
2973
2974 // If something supporting the roof collapsed, see what else collapses
2975 if( supports && !still_supports ) {
2976 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2977 // If z-levels are off, tz == t, so we end up skipping a lot of stuff to avoid bugs.
2978 const tripoint &tz = tripoint( t.xy(), t.z + 1 );
2979 // if nothing above us had the chance of collapsing, move on
2980 if( !one_in( collapse_check( tz ) ) ) {
2981 continue;
2982 }
2983 // if a wall collapses, walls without support from below risk collapsing and
2984 //propagate the collapse upwards
2985 if( zlevels && wall && p == t && has_flag( TFLAG_WALL, tz ) ) {
2986 collapse_at( tz, silent );
2987 }
2988 // floors without support from below risk collapsing into open air and can propagate
2989 // the collapse horizontally but not vertically
2990 if( p != t && ( has_flag( TFLAG_SUPPORTS_ROOF, t ) && has_flag( TFLAG_COLLAPSES, t ) ) ) {
2991 collapse_at( t, silent );
2992 }
2993 // this tile used to support a roof, now it doesn't, which means there is only
2994 // open air above us
2995 if( zlevels ) {
2996 ter_set( tz, t_open_air );
2997 furn_set( tz, f_null );
2999 }
3000 }
3001 }
3002 // it would be great to check if collapsing ceilings smashed through the floor, but
3003 // that's not handled for now
3004}
void crush(const tripoint &p)
Definition: map.cpp:3769
int collapse_check(const tripoint &p)
Checks if a square should collapse, returns the X for the one_in(X) collapse chance.
Definition: map.cpp:2912
void make_rubble(const tripoint &p, const furn_id &rubble_type, const ter_id &floor_type, bool overwrite=false)
Generates rubble at the given location, if overwrite is true it just writes on top of what currently ...
Definition: map.cpp:2592
@ TFLAG_COLLAPSES
Definition: mapdata.h:289
@ TFLAG_WALL
Definition: mapdata.h:301

References collapse_at(), collapse_check(), crush(), destroy(), f_null, furn_set(), has_flag(), make_rubble(), one_in(), points_in_radius(), propagate_suspension_check(), silent, t_open_air, ter_set(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, and zlevels.

Referenced by bash_ter_success(), collapse_at(), and talk_function::loot_building().

◆ collapse_check()

int map::collapse_check ( const tripoint p)

Checks if a square should collapse, returns the X for the one_in(X) collapse chance.

Definition at line 2912 of file map.cpp.

2913{
2914 const bool collapses = has_flag( TFLAG_COLLAPSES, p );
2915 const bool supports_roof = has_flag( TFLAG_SUPPORTS_ROOF, p );
2916
2917 int num_supports = p.z == -OVERMAP_DEPTH ? 0 : -5;
2918 // if there's support below, things are less likely to collapse
2919 if( p.z > -OVERMAP_DEPTH ) {
2920 const tripoint &pbelow = tripoint( p.xy(), p.z - 1 );
2921 for( const tripoint &tbelow : points_in_radius( pbelow, 1 ) ) {
2922 if( has_flag( TFLAG_SUPPORTS_ROOF, pbelow ) ) {
2923 num_supports += 1;
2924 if( has_flag( TFLAG_WALL, pbelow ) ) {
2925 num_supports += 2;
2926 }
2927 if( tbelow == pbelow ) {
2928 num_supports += 2;
2929 }
2930 }
2931 }
2932 }
2933
2934 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2935 if( p == t ) {
2936 continue;
2937 }
2938
2939 if( collapses ) {
2940 if( has_flag( TFLAG_COLLAPSES, t ) ) {
2941 num_supports++;
2942 } else if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2943 num_supports += 2;
2944 }
2945 } else if( supports_roof ) {
2946 if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2947 if( has_flag( TFLAG_WALL, t ) ) {
2948 num_supports += 4;
2949 } else if( !has_flag( TFLAG_COLLAPSES, t ) ) {
2950 num_supports += 3;
2951 }
2952 }
2953 }
2954 }
2955
2956 return 1.7 * num_supports;
2957}

References has_flag(), OVERMAP_DEPTH, points_in_radius(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, tripoint::xy(), and tripoint::z.

Referenced by collapse_at().

◆ collapse_invalid_suspension()

void map::collapse_invalid_suspension ( const tripoint point)

Triggers a recursive collapse of suspended tiles based on their support validity.

Definition at line 3015 of file map.cpp.

3016{
3017 if( !is_suspension_valid( point ) ) {
3019 furn_set( point, f_null );
3020
3022 }
3023}
bool is_suspension_valid(const tripoint &point)
Checks the four orientations in which a suspended tile could be valid, and returns if the tile is val...
Definition: map.cpp:3025

References f_null, furn_set(), is_suspension_valid(), propagate_suspension_check(), t_open_air, and ter_set().

Referenced by drop_everything(), and propagate_suspension_check().

◆ combined_movecost()

int map::combined_movecost ( const tripoint from,
const tripoint to,
const vehicle ignored_vehicle = nullptr,
int  modifier = 0,
bool  flying = false,
bool  via_ramp = false 
) const

Cost to move out of one tile and into the next.

Returns
The cost in turns to move out of tripoint from and into to

Definition at line 1903 of file map.cpp.

1906{
1907 const int mults[4] = { 0, 50, 71, 100 };
1908 const int cost1 = move_cost( from, ignored_vehicle );
1909 const int cost2 = move_cost( to, ignored_vehicle );
1910 // Multiply cost depending on the number of differing axes
1911 // 0 if all axes are equal, 100% if only 1 differs, 141% for 2, 200% for 3
1912 size_t match = trigdist ? ( from.x != to.x ) + ( from.y != to.y ) + ( from.z != to.z ) : 1;
1913 if( flying || from.z == to.z ) {
1914 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1915 }
1916
1917 // Inter-z-level movement by foot (not flying)
1918 if( !valid_move( from, to, false, via_ramp ) ) {
1919 return 0;
1920 }
1921
1922 // TODO: Penalize for using stairs
1923 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1924}
bool valid_move(const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
Returns true if a creature could walk from from to to in one step.
Definition: map.cpp:1926

References move_cost(), trigdist, valid_move(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::walk_move().

◆ computer_at()

computer * map::computer_at ( const tripoint p)

Definition at line 5682 of file map.cpp.

5683{
5684 if( !inbounds( p ) ) {
5685 return nullptr;
5686 }
5687
5688 point l;
5689 submap *const sm = get_submap_at( p, l );
5690 return sm->get_computer( l );
5691}

References get_submap_at(), inbounds(), and coords::sm.

Referenced by mission_start::reveal_lab_train_depot(), and game::use_computer().

◆ copy_grid()

void map::copy_grid ( const tripoint to,
const tripoint from 
)
protected

Definition at line 7649 of file map.cpp.

7650{
7651 const auto smap = get_submap_at_grid( from );
7652 setsubmap( get_nonant( to ), smap );
7653 for( auto &it : smap->vehicles ) {
7654 it->sm_pos = to;
7655 }
7656}
void setsubmap(size_t grididx, submap *smap)
Set the submap pointer in grid at the give index.
Definition: map.cpp:8447
size_t get_nonant(const tripoint &gridp) const
Get the index of a submap pointer in the grid given by grid coordinates.
Definition: map.cpp:8480

References get_nonant(), get_submap_at_grid(), and setsubmap().

Referenced by shift().

◆ could_see_items() [1/2]

bool map::could_see_items ( const tripoint p,
const Creature who 
) const

Check if the creature could see items at p if there were any items.

This is similar to sees_some_items, but it does not check that there are actually any items.

Definition at line 4867 of file map.cpp.

4868{
4869 return could_see_items( p, who.pos() );
4870}
virtual const tripoint & pos() const =0
bool could_see_items(const tripoint &p, const Creature &who) const
Check if the creature could see items at p if there were any items.
Definition: map.cpp:4867

References could_see_items(), and Creature::pos().

Referenced by could_see_items(), game::print_items_info(), and sees_some_items().

◆ could_see_items() [2/2]

bool map::could_see_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4872 of file map.cpp.

4873{
4874 static const std::string container_string( "CONTAINER" );
4875 const bool container = has_flag_ter_or_furn( container_string, p );
4876 const bool sealed = has_flag_ter_or_furn( TFLAG_SEALED, p );
4877 if( sealed && container ) {
4878 // never see inside of sealed containers
4879 return false;
4880 }
4881 if( container ) {
4882 // can see inside of containers if adjacent or
4883 // on top of the container
4884 return ( std::abs( p.x - from.x ) <= 1 &&
4885 std::abs( p.y - from.y ) <= 1 &&
4886 std::abs( p.z - from.z ) <= 1 );
4887 }
4888 return true;
4889}
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2404
@ TFLAG_SEALED
Definition: mapdata.h:286

References has_flag_ter_or_furn(), TFLAG_SEALED, tripoint::x, tripoint::y, and tripoint::z.

◆ coverage()

int map::coverage ( const tripoint p) const

Returns coverage value of the tile.

Definition at line 6384 of file map.cpp.

6385{
6386 if( const auto obstacle_f = furn( p ) ) {
6387 return obstacle_f->coverage;
6388 }
6389 if( const auto vp = veh_at( p ) ) {
6390 if( vp->obstacle_at_part() ) {
6391 return 60;
6392 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) &&
6393 !vp->part_with_feature( "PROTRUSION", true ) ) {
6394 return 45;
6395 }
6396 }
6397 return ter( p )->coverage;
6398}
@ VPFLAG_AISLE
Definition: veh_type.h:40

References map_data_common_t::coverage, furn(), ter(), veh_at(), and VPFLAG_AISLE.

Referenced by build_vision_transparency_cache(), and game::print_terrain_info().

◆ create_anomaly() [1/2]

void map::create_anomaly ( const tripoint p,
artifact_natural_property  prop,
bool  create_rubble = true 
)

Definition at line 6158 of file mapgen.cpp.

6159{
6160 // TODO: Z
6161 point c( cp.xy() );
6162 if( create_rubble ) {
6163 rough_circle( this, t_dirt, c, 11 );
6164 rough_circle_furn( this, f_rubble, c, 5 );
6165 furn_set( c, f_null );
6166 }
6167 switch( prop ) {
6168 case ARTPROP_WRIGGLING:
6169 case ARTPROP_MOVING:
6170 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6171 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6172 if( furn( point( i, j ) ) == f_rubble ) {
6173 add_field( {i, j, abs_sub.z}, fd_push_items, 1 );
6174 }
6175 }
6176 }
6177 break;
6178
6179 case ARTPROP_GLOWING:
6180 case ARTPROP_GLITTERING:
6181 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6182 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6183 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6184 mtrap_set( this, point( i, j ), tr_glow );
6185 }
6186 }
6187 }
6188 break;
6189
6190 case ARTPROP_HUMMING:
6191 case ARTPROP_RATTLING:
6192 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6193 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6194 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6195 mtrap_set( this, point( i, j ), tr_hum );
6196 }
6197 }
6198 }
6199 break;
6200
6201 case ARTPROP_WHISPERING:
6202 case ARTPROP_ENGRAVED:
6203 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6204 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6205 if( furn( point( i, j ) ) == f_rubble && one_in( 3 ) ) {
6206 mtrap_set( this, point( i, j ), tr_shadow );
6207 }
6208 }
6209 }
6210 break;
6211
6212 case ARTPROP_BREATHING:
6213 for( int i = c.x - 1; i <= c.x + 1; i++ ) {
6214 for( int j = c.y - 1; j <= c.y + 1; j++ ) {
6215 if( i == c.x && j == c.y ) {
6216 place_spawns( GROUP_BREATHER_HUB, 1, point( i, j ), point( i, j ), 1,
6217 true );
6218 } else {
6219 place_spawns( GROUP_BREATHER, 1, point( i, j ), point( i, j ), 1, true );
6220 }
6221 }
6222 }
6223 break;
6224
6225 case ARTPROP_DEAD:
6226 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6227 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6228 if( furn( point( i, j ) ) == f_rubble ) {
6229 mtrap_set( this, point( i, j ), tr_drain );
6230 }
6231 }
6232 }
6233 break;
6234
6235 case ARTPROP_ITCHY:
6236 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6237 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6238 if( furn( point( i, j ) ) == f_rubble ) {
6239 set_radiation( point( i, j ), rng( 0, 10 ) );
6240 }
6241 }
6242 }
6243 break;
6244
6245 case ARTPROP_ELECTRIC:
6246 case ARTPROP_CRACKLING:
6247 add_field( {c, abs_sub.z}, fd_shock_vent, 3 );
6248 break;
6249
6250 case ARTPROP_SLIMY:
6251 add_field( {c, abs_sub.z}, fd_acid_vent, 3 );
6252 break;
6253
6254 case ARTPROP_WARM:
6255 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6256 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6257 if( furn( point( i, j ) ) == f_rubble ) {
6258 add_field( {i, j, abs_sub.z}, fd_fire_vent, 1 + ( rl_dist( c, point( i, j ) ) % 3 ) );
6259 }
6260 }
6261 }
6262 break;
6263
6264 case ARTPROP_SCALED:
6265 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6266 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6267 if( furn( point( i, j ) ) == f_rubble ) {
6268 mtrap_set( this, point( i, j ), tr_snake );
6269 }
6270 }
6271 }
6272 break;
6273
6274 case ARTPROP_FRACTAL:
6275 create_anomaly( c + point( -4, -4 ),
6276 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6277 create_anomaly( c + point( 4, -4 ),
6278 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6279 create_anomaly( c + point( -4, 4 ),
6280 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6281 create_anomaly( c + point( 4, -4 ),
6282 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6283 break;
6284 default:
6285 break;
6286 }
6287}
bool add_field(const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
Add field entry at point, or set intensity if present.
Definition: map.cpp:5536
void create_anomaly(const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
Definition: mapgen.cpp:6158
void set_radiation(const tripoint &p, int value)
Definition: map.cpp:4166
void place_spawns(const mongroup_id &group, int chance, point p1, point p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
Definition: mapgen.cpp:5228
artifact_natural_property
Definition: enums.h:152
@ ARTPROP_GLITTERING
Definition: enums.h:162
@ ARTPROP_ITCHY
Definition: enums.h:161
@ ARTPROP_RATTLING
Definition: enums.h:168
@ ARTPROP_WRIGGLING
Definition: enums.h:154
@ ARTPROP_HUMMING
Definition: enums.h:156
@ ARTPROP_WHISPERING
Definition: enums.h:158
@ ARTPROP_ENGRAVED
Definition: enums.h:165
@ ARTPROP_ELECTRIC
Definition: enums.h:163
@ ARTPROP_FRACTAL
Definition: enums.h:170
@ ARTPROP_SCALED
Definition: enums.h:169
@ ARTPROP_GLOWING
Definition: enums.h:155
@ ARTPROP_NULL
Definition: enums.h:153
@ ARTPROP_DEAD
Definition: enums.h:160
@ ARTPROP_BREATHING
Definition: enums.h:159
@ ARTPROP_MAX
Definition: enums.h:171
@ ARTPROP_CRACKLING
Definition: enums.h:166
@ ARTPROP_WARM
Definition: enums.h:167
@ ARTPROP_MOVING
Definition: enums.h:157
@ ARTPROP_SLIMY
Definition: enums.h:164
field_type_id fd_fire_vent
Definition: field_type.cpp:351
field_type_id fd_acid_vent
Definition: field_type.cpp:357
field_type_id fd_push_items
Definition: field_type.cpp:355
field_type_id fd_shock_vent
Definition: field_type.cpp:356
furn_id f_rubble
Definition: mapdata.cpp:1100
void rough_circle(map *m, const ter_id &type, point p, int rad)
Definition: mapgen.cpp:6322
static const mongroup_id GROUP_BREATHER("GROUP_BREATHER")
void rough_circle_furn(map *m, const furn_id &type, point p, int rad)
Definition: mapgen.cpp:6326
static const mongroup_id GROUP_BREATHER_HUB("GROUP_BREATHER_HUB")
void mtrap_set(map *m, point p, trap_id type)
static const trap_str_id tr_drain("tr_drain")
static const trap_str_id tr_snake("tr_snake")
static const trap_str_id tr_shadow("tr_shadow")
trap_id tr_glow
Definition: trap.cpp:312
trap_id tr_hum
Definition: trap.cpp:313

References abs_sub, add_field(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_DEAD, ARTPROP_ELECTRIC, ARTPROP_ENGRAVED, ARTPROP_FRACTAL, ARTPROP_GLITTERING, ARTPROP_GLOWING, ARTPROP_HUMMING, ARTPROP_ITCHY, ARTPROP_MAX, ARTPROP_MOVING, ARTPROP_NULL, ARTPROP_RATTLING, ARTPROP_SCALED, ARTPROP_SLIMY, ARTPROP_WARM, ARTPROP_WHISPERING, ARTPROP_WRIGGLING, c, create_anomaly(), f_null, f_rubble, fd_acid_vent, fd_fire_vent, fd_push_items, fd_shock_vent, furn(), furn_set(), GROUP_BREATHER, GROUP_BREATHER_HUB, mtrap_set(), one_in(), place_spawns(), rl_dist(), rng(), rough_circle(), rough_circle_furn(), set_radiation(), t_dirt, tr_drain, tr_glow, tr_hum, tr_shadow, tr_snake, tripoint::xy(), and tripoint::z.

Referenced by create_anomaly(), debug_menu::debug(), draw_lab(), and MapExtras::mx_portal_in().

◆ create_anomaly() [2/2]

void map::create_anomaly ( point  cp,
artifact_natural_property  prop,
bool  create_rubble = true 
)
inline

Definition at line 1333 of file map.h.

1333 {
1334 create_anomaly( tripoint( cp, abs_sub.z ), prop, create_rubble );
1335 }

References abs_sub, create_anomaly(), and tripoint::z.

◆ create_burnproducts()

void map::create_burnproducts ( const tripoint p,
const item fuel,
const units::mass burned_mass 
)

Definition at line 97 of file map_field.cpp.

98{
99 std::vector<material_id> all_mats = fuel.made_of();
100 if( all_mats.empty() ) {
101 return;
102 }
103 // Items that are multiple materials are assumed to be equal parts each.
104 const units::mass by_weight = burned_mass / all_mats.size();
105 for( material_id &mat : all_mats ) {
106 for( auto &bp : mat->burn_products() ) {
107 itype_id id = bp.first;
108 // Spawning the same item as the one that was just burned is pointless
109 // and leads to infinite recursion.
110 if( fuel.typeId() == id ) {
111 continue;
112 }
113 const float eff = bp.second;
114 const int n = std::floor( eff * ( by_weight / id->weight ) );
115
116 if( n <= 0 ) {
117 continue;
118 }
119 spawn_item( p, id, n, 1, calendar::turn );
120 }
121 }
122}
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
Definition: map.cpp:4314
const std::string id
Definition: basecamp.h:87

References base_camps::id, item::made_of(), spawn_item(), calendar::turn, and item::typeId().

Referenced by MapExtras::burned_ground_parser(), and process_fields_in_submap().

◆ create_hot_air()

void map::create_hot_air ( const tripoint p,
int  intensity 
)
private

Definition at line 364 of file map_field.cpp.

365{
366 field_type_id hot_air;
367 switch( intensity ) {
368 case 1:
369 hot_air = fd_hot_air1;
370 break;
371 case 2:
372 hot_air = fd_hot_air2;
373 break;
374 case 3:
375 hot_air = fd_hot_air3;
376 break;
377 case 4:
378 hot_air = fd_hot_air4;
379 break;
380 default:
381 debugmsg( "Tried to spread hot air with intensity %d", intensity );
382 return;
383 }
384
385 for( int counter = 0; counter < 5; counter++ ) {
386 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
387 add_field( dst, hot_air, 1 );
388 }
389}
field_type_id fd_hot_air3
Definition: field_type.cpp:381
field_type_id fd_hot_air2
Definition: field_type.cpp:380
field_type_id fd_hot_air1
Definition: field_type.cpp:379
field_type_id fd_hot_air4
Definition: field_type.cpp:382

References add_field(), debugmsg, fd_hot_air1, fd_hot_air2, fd_hot_air3, fd_hot_air4, and rng().

Referenced by process_fields_in_submap().

◆ creature_in_field()

void map::creature_in_field ( Creature critter)

Apply field effects to the creature when it's on a square with fields.

Definition at line 1563 of file map_field.cpp.

1564{
1565 bool in_vehicle = false;
1566 bool inside_vehicle = false;
1567 player *u = critter.as_player();
1568 if( critter.is_monster() ) {
1569 monster_in_field( *static_cast<monster *>( &critter ) );
1570 } else {
1571 if( u ) {
1572 in_vehicle = u->in_vehicle;
1573 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1574 // and what part of the vehicle we need to deal with.
1575 if( in_vehicle ) {
1576 if( const optional_vpart_position vp = veh_at( u->pos() ) ) {
1577 if( vp->is_inside() ) {
1578 inside_vehicle = true;
1579 }
1580 }
1581 }
1582 player_in_field( *u );
1583 }
1584 }
1585
1586 field &curfield = get_field( critter.pos() );
1587 for( auto &field_entry_it : curfield ) {
1588 field_entry &cur_field_entry = field_entry_it.second;
1589 if( !cur_field_entry.is_field_alive() ) {
1590 continue;
1591 }
1592 const field_type_id cur_field_id = cur_field_entry.get_field_type();
1593
1594 for( const auto &fe : cur_field_entry.field_effects() ) {
1595 if( in_vehicle && fe.immune_in_vehicle ) {
1596 continue;
1597 }
1598 if( inside_vehicle && fe.immune_inside_vehicle ) {
1599 continue;
1600 }
1601 if( !inside_vehicle && fe.immune_outside_vehicle ) {
1602 continue;
1603 }
1604 if( in_vehicle && !one_in( fe.chance_in_vehicle ) ) {
1605 continue;
1606 }
1607 if( inside_vehicle && !one_in( fe.chance_inside_vehicle ) ) {
1608 continue;
1609 }
1610 if( !inside_vehicle && !one_in( fe.chance_outside_vehicle ) ) {
1611 continue;
1612 }
1613
1614 const effect field_fx = fe.get_effect();
1615 if( critter.is_immune_field( cur_field_id ) || critter.is_immune_effect( field_fx.get_id() ) ) {
1616 continue;
1617 }
1618 bool effect_added = false;
1619 if( fe.is_environmental ) {
1620 effect_added = critter.add_env_effect( fe.id, fe.bp->token, fe.intensity, fe.get_duration() );
1621 } else {
1622 effect_added = true;
1623 critter.add_effect( field_fx );
1624 }
1625 if( effect_added ) {
1626 critter.add_msg_player_or_npc( fe.env_message_type, fe.get_message(), fe.get_message_npc() );
1627 }
1628 }
1629 }
1630}
bool in_vehicle
Definition: character.h:1573
virtual bool is_monster() const
Definition: creature.h:101
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:331
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:689
virtual player * as_player()
Definition: creature.h:122
virtual bool is_immune_effect(const efftype_id &type) const =0
Definition: effect.h:164
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:308
std::vector< field_effect > field_effects() const
Definition: field.cpp:294
bool is_field_alive()
Definition: field.h:89
field_type_id get_field_type() const
Definition: field.cpp:105
A variable sized collection of field entries on a given map square.
Definition: field.h:131
void player_in_field(player &u)
Definition: map_field.cpp:1224
void monster_in_field(monster &z)
Definition: map_field.cpp:1632

References Creature::add_effect(), Creature::add_env_effect(), Creature::add_msg_player_or_npc(), Creature::as_player(), field_entry::field_effects(), get_field(), field_entry::get_field_type(), effect::get_id(), Character::in_vehicle, field_entry::is_field_alive(), Creature::is_immune_effect(), Creature::is_immune_field(), Creature::is_monster(), monster_in_field(), one_in(), player_in_field(), Creature::pos(), Character::pos(), and veh_at().

Referenced by add_field(), game::do_turn(), game::monmove(), and game::place_player().

◆ creature_on_trap()

void map::creature_on_trap ( Creature critter,
bool  may_avoid = true 
)

Apply trap effects to the creature, similar to creature_in_field.

If there is no trap at the creatures location, nothing is done. If the creature can avoid the trap, nothing is done as well. Otherwise the trap is triggered.

Parameters
critterCreature that just got trapped
may_avoidIf true, the creature tries to avoid the trap (Creature::avoid_trap). If false, the trap is always triggered.

Definition at line 8629 of file map.cpp.

8630{
8631 const auto &tr = tr_at( c.pos() );
8632 if( tr.is_null() ) {
8633 return;
8634 }
8635 // boarded in a vehicle means the player is above the trap, like a flying monster and can
8636 // never trigger the trap.
8637 const player *const p = dynamic_cast<const player *>( &c );
8638 if( p != nullptr && p->in_vehicle ) {
8639 return;
8640 }
8641 if( may_avoid && c.avoid_trap( c.pos(), tr ) ) {
8642 return;
8643 }
8644 tr.trigger( c.pos(), &c );
8645}

References c, Character::in_vehicle, and tr_at().

Referenced by game::fling_creature(), game::phasing_move(), game::place_player(), and game::vertical_move().

◆ crush()

void map::crush ( const tripoint p)

Definition at line 3769 of file map.cpp.

3770{
3771 player *crushed_player = g->critter_at<player>( p );
3772
3773 if( crushed_player != nullptr ) {
3774 bool player_inside = false;
3775 if( crushed_player->in_vehicle ) {
3776 const optional_vpart_position vp = veh_at( p );
3777 player_inside = vp && vp->is_inside();
3778 }
3779 if( !player_inside ) { //If there's a player at p and he's not in a covered vehicle...
3780 //This is the roof coming down on top of us, no chance to dodge
3781 crushed_player->add_msg_player_or_npc( m_bad, _( "You are crushed by the falling debris!" ),
3782 _( "<npcname> is crushed by the falling debris!" ) );
3783 // TODO: Make this depend on the ceiling material
3784 const int dam = rng( 0, 40 );
3785 // Torso and head take the brunt of the blow
3786 crushed_player->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH,
3787 dam * .25 ) );
3788 crushed_player->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH,
3789 dam * .45 ) );
3790 // Legs take the next most through transferred force
3791 crushed_player->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH,
3792 dam * .10 ) );
3793 crushed_player->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH,
3794 dam * .10 ) );
3795 // Arms take the least
3796 crushed_player->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH,
3797 dam * .05 ) );
3798 crushed_player->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH,
3799 dam * .05 ) );
3800
3801 // Pin whoever got hit
3802 crushed_player->add_effect( effect_crushed, 1_turns, num_bp );
3803 crushed_player->check_dead_state();
3804 }
3805 }
3806
3807 if( monster *const monhit = g->critter_at<monster>( p ) ) {
3808 // 25 ~= 60 * .45 (torso)
3809 monhit->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( 0, 25 ) ) );
3810
3811 // Pin whoever got hit
3812 monhit->add_effect( effect_crushed, 1_turns, num_bp );
3813 monhit->check_dead_state();
3814 }
3815
3816 if( const optional_vpart_position vp = veh_at( p ) ) {
3817 // Arbitrary number is better than collapsing house roof crushing APCs
3818 vp->vehicle().damage( vp->part_index(), rng( 100, 1000 ), DT_BASH, false );
3819 }
3820}
int_id< body_part_type > bodypart_id
Definition: bodypart.h:25
@ num_bp
Definition: bodypart.h:54
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1899
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:372
@ m_bad
Definition: enums.h:261
static const efftype_id effect_crushed("crushed")

References _, Creature::add_effect(), player::add_msg_player_or_npc(), Creature::check_dead_state(), Character::deal_damage(), DT_BASH, effect_crushed, g, Character::in_vehicle, m_bad, num_bp, rng(), and veh_at().

Referenced by collapse_at().

◆ dangerous_field_at()

bool map::dangerous_field_at ( const tripoint p)

Definition at line 5525 of file map.cpp.

5526{
5527 for( auto &pr : field_at( p ) ) {
5528 auto &fd = pr.second;
5529 if( fd.is_dangerous() ) {
5530 return true;
5531 }
5532 }
5533 return false;
5534}
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5420

References field_at().

◆ decay_cosmetic_fields()

void map::decay_cosmetic_fields ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Definition at line 7527 of file map.cpp.

7529{
7530 for( auto &pr : field_at( p ) ) {
7531 auto &fd = pr.second;
7532 const time_duration hl = fd.get_field_type().obj().half_life;
7533 if( !fd.decays_on_actualize() || hl <= 0_turns ) {
7534 continue;
7535 }
7536
7537 const time_duration added_age = 2 * time_since_last_actualize / rng( 2, 4 );
7538 fd.mod_field_age( added_age );
7539 const int intensity_drop = fd.get_field_age() / hl;
7540 if( intensity_drop > 0 ) {
7541 fd.set_field_intensity( fd.get_field_intensity() - intensity_drop );
7542 fd.mod_field_age( -hl * intensity_drop );
7543 }
7544 }
7545}

References field_at(), and rng().

Referenced by actualize().

◆ decay_fields_and_scent()

void map::decay_fields_and_scent ( const time_duration amount)

Moved here from weather.cpp for speed.

Decays fire, washable fields and scent. Washable fields are decayed only by 1/3 of the amount fire is.

Definition at line 2726 of file map.cpp.

2727{
2728 // TODO: Make this happen on all z-levels
2729
2730 // Decay scent separately, so that later we can use field count to skip empty submaps
2731 g->scent.decay();
2732
2733 // Coordinate code copied from lightmap calculations
2734 // TODO: Z
2735 const int smz = abs_sub.z;
2736 const auto &outside_cache = get_cache_ref( smz ).outside_cache;
2737 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
2738 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
2739 const auto cur_submap = get_submap_at_grid( { smx, smy, smz } );
2740 int to_proc = cur_submap->field_count;
2741 if( to_proc < 1 ) {
2742 if( to_proc < 0 ) {
2743 cur_submap->field_count = 0;
2744 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2745 << ( abs_sub + tripoint( smx, smy, 0 ) )
2746 << "has " << to_proc << " field_count";
2747 }
2748 get_cache( smz ).field_cache.reset( smx + ( smy * MAPSIZE ) );
2749 // This submap has no fields
2750 continue;
2751 }
2752
2753 for( int sx = 0; sx < SEEX; ++sx ) {
2754 if( to_proc < 1 ) {
2755 // This submap had some fields, but all got proc'd already
2756 break;
2757 }
2758
2759 for( int sy = 0; sy < SEEY; ++sy ) {
2760 const int x = sx + smx * SEEX;
2761 const int y = sy + smy * SEEY;
2762
2763 field &fields = cur_submap->get_field( { sx, sy} );
2764 if( !outside_cache[x][y] ) {
2765 to_proc -= fields.field_count();
2766 continue;
2767 }
2768
2769 for( auto &fp : fields ) {
2770 to_proc--;
2771 field_entry &cur = fp.second;
2772 const field_type_id type = cur.get_field_type();
2773 const int decay_amount_factor = type.obj().decay_amount_factor;
2774 if( decay_amount_factor != 0 ) {
2775 const time_duration decay_amount = amount / decay_amount_factor;
2776 cur.set_field_age( cur.get_field_age() + decay_amount );
2777 }
2778 }
2779 }
2780 }
2781
2782 if( to_proc > 0 ) {
2783 cur_submap->field_count = cur_submap->field_count - to_proc;
2784 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2785 << abs_sub + tripoint( smx, smy, 0 )
2786 << "has " << cur_submap->field_count - to_proc << "fields, but "
2787 << cur_submap->field_count << " field_count";
2788 }
2789 }
2790 }
2791}
time_duration set_field_age(const time_duration &new_age)
Sets age to the given value.
Definition: field.cpp:138
time_duration get_field_age() const
Definition: field.cpp:133
@ Error
Error (default: enabled).

References abs_sub, dbg, Error, level_cache::field_cache, submap::field_count, g, get_cache(), get_cache_ref(), field_entry::get_field_age(), field_entry::get_field_type(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, level_cache::outside_cache, SEEX, SEEY, field_entry::set_field_age(), sx, sy, type, and tripoint::z.

◆ delete_graffiti()

void map::delete_graffiti ( const tripoint p)

Definition at line 7959 of file map.cpp.

7960{
7961 if( !inbounds( p ) ) {
7962 return;
7963 }
7964 point l;
7965 submap *const current_submap = get_submap_at( p, l );
7966 current_submap->delete_graffiti( l );
7967}
void delete_graffiti(point p)
Definition: submap.cpp:145

References submap::delete_graffiti(), get_submap_at(), and inbounds().

◆ delete_signage()

void map::delete_signage ( const tripoint p) const

Definition at line 4142 of file map.cpp.

4143{
4144 if( !inbounds( p ) ) {
4145 return;
4146 }
4147
4148 point l;
4149 submap *const current_submap = get_submap_at( p, l );
4150
4151 current_submap->delete_signage( l );
4152}
void delete_signage(point p)
Definition: submap.cpp:184

References submap::delete_signage(), get_submap_at(), and inbounds().

Referenced by bash_furn_success(), and talk_function::loot_building().

◆ deregister_vehicle_zone()

bool map::deregister_vehicle_zone ( zone_data zone)

Definition at line 1023 of file map.cpp.

1024{
1025 if( const std::optional<vpart_reference> vp = veh_at( getlocal(
1026 zone.get_start_point() ) ).part_with_feature( "CARGO", false ) ) {
1027 auto bounds = vp->vehicle().loot_zones.equal_range( vp->mount() );
1028 for( auto it = bounds.first; it != bounds.second; it++ ) {
1029 if( &zone == &( it->second ) ) {
1030 vp->vehicle().loot_zones.erase( it );
1031 return true;
1032 }
1033 }
1034 }
1035 return false;
1036}
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8417
tripoint get_start_point() const
Definition: clzones.h:314

References zone_data::get_start_point(), getlocal(), optional_vpart_position::part_with_feature(), and veh_at().

◆ destroy()

void map::destroy ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until it can't be bashed anymore.

Definition at line 3735 of file map.cpp.

3736{
3737 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3738 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3739
3740 // If we were destroying a floor, allow destroying floors
3741 // If we were destroying something unpassable, destroy only that
3742 bool was_impassable = impassable( p );
3743 int count = 0;
3744 while( count <= 25
3745 && bash( p, 999, silent, true ).success
3746 && ( !was_impassable || impassable( p ) ) ) {
3747 count++;
3748 }
3749}

References bash(), detail::count(), impassable(), silent, and behavior::success.

Referenced by add_vehicle_to_map(), bash(), MapExtras::burned_ground_parser(), collapse_at(), draw_lab(), make_rubble(), MapExtras::mx_crater(), MapExtras::mx_helicopter(), MapExtras::mx_supplydrop(), om_cutdown_trees(), and process_fields_in_submap().

◆ destroy_furn()

void map::destroy_furn ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until there is no more furniture.

Definition at line 3751 of file map.cpp.

3752{
3753 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3754 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3755 int count = 0;
3756 while( count <= 25 && furn( p ) != f_null && bash( p, 999, silent, true ).success ) {
3757 count++;
3758 }
3759}

References bash(), detail::count(), f_null, furn(), silent, and behavior::success.

Referenced by make_rubble().

◆ destroy_vehicle()

void map::destroy_vehicle ( vehicle veh)

Definition at line 460 of file map.cpp.

461{
462 detach_vehicle( veh );
463}

References detach_vehicle().

Referenced by MapExtras::burned_ground_parser(), and MapExtras::mx_burned_ground().

◆ detach_vehicle()

std::unique_ptr< vehicle > map::detach_vehicle ( vehicle veh)

Definition at line 414 of file map.cpp.

415{
416 if( veh == nullptr ) {
417 debugmsg( "map::detach_vehicle was passed nullptr" );
418 return std::unique_ptr<vehicle>();
419 }
420
421 int z = veh->sm_pos.z;
422 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
423 debugmsg( "detach_vehicle got a vehicle outside allowed z-level range! name=%s, submap:%d,%d,%d",
424 veh->name, veh->sm_pos.x, veh->sm_pos.y, veh->sm_pos.z );
425 // Try to fix by moving the vehicle here
426 z = veh->sm_pos.z = abs_sub.z;
427 }
428
429 // Unboard all passengers before detaching
430 for( auto const &part : veh->get_avail_parts( VPFLAG_BOARDABLE ) ) {
431 player *passenger = part.get_passenger();
432 if( passenger ) {
433 unboard_vehicle( part, passenger );
434 }
435 }
436 veh->invalidate_towing( true );
437 submap *const current_submap = get_submap_at_grid( veh->sm_pos );
438 level_cache &ch = get_cache( z );
439 for( size_t i = 0; i < current_submap->vehicles.size(); i++ ) {
440 if( current_submap->vehicles[i].get() == veh ) {
441 ch.vehicle_list.erase( veh );
442 ch.zone_vehicles.erase( veh );
444 std::unique_ptr<vehicle> result = std::move( current_submap->vehicles[i] );
445 current_submap->vehicles.erase( current_submap->vehicles.begin() + i );
446 if( veh->tracking_on ) {
448 }
449 dirty_vehicle_list.erase( veh );
450 veh->detach();
451 veh->refresh_position();
452 return result;
453 }
454 }
455 debugmsg( "detach_vehicle can't find it! name=%s, submap:%d,%d,%d", veh->name, veh->sm_pos.x,
456 veh->sm_pos.y, veh->sm_pos.z );
457 return std::unique_ptr<vehicle>();
458}
std::set< vehicle * > dirty_vehicle_list
Definition: map.h:1600
void reset_vehicle_cache()
Definition: map.cpp:314
void remove_vehicle(const vehicle *veh)
Remove the vehicle from being tracked in the overmap.
std::string name
Definition: vehicle.h:1581
void refresh_position()
Definition: vehicle.cpp:5838
bool tracking_on
Definition: vehicle.h:1723
void invalidate_towing(bool first_vehicle=false)
Definition: vehicle.cpp:6152
void detach()
Definition: vehicle.h:476
std::set< vehicle * > zone_vehicles
Definition: map.h:358
std::set< vehicle * > vehicle_list
Definition: map.h:357

References abs_sub, debugmsg, vehicle::detach(), dirty_vehicle_list, vehicle::get_avail_parts(), get_cache(), get_submap_at_grid(), vehicle::invalidate_towing(), avatar_action::move(), vehicle::name, overmap_buffer, OVERMAP_HEIGHT, vehicle::refresh_position(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), vehicle::sm_pos, vehicle::tracking_on, unboard_vehicle(), level_cache::vehicle_list, submap::vehicles, VPFLAG_BOARDABLE, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by add_vehicle_to_map(), destroy_vehicle(), and editmap::mapgen_veh_destroy().

◆ determine_wall_corner()

int map::determine_wall_corner ( const tripoint p) const
private

Definition at line 7990 of file map.cpp.

7991{
7992 int test_connect_group = ter( p ).obj().connect_group;
7993 uint8_t connections = get_known_connections( p, test_connect_group );
7994 // The bits in connections are SEWN, whereas the characters in LINE_
7995 // constants are NESW, so we want values in 8 | 2 | 1 | 4 order.
7996 switch( connections ) {
7997 case 8 | 2 | 1 | 4:
7998 return LINE_XXXX;
7999 case 0 | 2 | 1 | 4:
8000 return LINE_OXXX;
8001
8002 case 8 | 0 | 1 | 4:
8003 return LINE_XOXX;
8004 case 0 | 0 | 1 | 4:
8005 return LINE_OOXX;
8006
8007 case 8 | 2 | 0 | 4:
8008 return LINE_XXOX;
8009 case 0 | 2 | 0 | 4:
8010 return LINE_OXOX;
8011 case 8 | 0 | 0 | 4:
8012 return LINE_XOOX;
8013 case 0 | 0 | 0 | 4:
8014 return LINE_OXOX; // LINE_OOOX would be better
8015
8016 case 8 | 2 | 1 | 0:
8017 return LINE_XXXO;
8018 case 0 | 2 | 1 | 0:
8019 return LINE_OXXO;
8020 case 8 | 0 | 1 | 0:
8021 return LINE_XOXO;
8022 case 0 | 0 | 1 | 0:
8023 return LINE_XOXO; // LINE_OOXO would be better
8024 case 8 | 2 | 0 | 0:
8025 return LINE_XXOO;
8026 case 0 | 2 | 0 | 0:
8027 return LINE_OXOX; // LINE_OXOO would be better
8028 case 8 | 0 | 0 | 0:
8029 return LINE_XOXO; // LINE_XOOO would be better
8030
8031 case 0 | 0 | 0 | 0:
8032 return ter( p ).obj().symbol(); // technically just a column
8033
8034 default:
8035 // assert( false );
8036 // this shall not happen
8037 return '?';
8038 }
8039}
uint8_t get_known_connections(const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
Definition: map.cpp:1575
generic_factory< overmap_connection > connections("overmap connection")
#define LINE_XOXX
Definition: output.h:47
#define LINE_XOXO
Definition: output.h:39
#define LINE_OXOX
Definition: output.h:40
#define LINE_OOXX
Definition: output.h:43
#define LINE_OXXX
Definition: output.h:48
#define LINE_XXXO
Definition: output.h:45
#define LINE_XXOX
Definition: output.h:46
#define LINE_OXXO
Definition: output.h:42
#define LINE_XOOX
Definition: output.h:44
#define LINE_XXOO
Definition: output.h:41
#define LINE_XXXX
Definition: output.h:49
int symbol() const
Definition: mapdata.cpp:553

References map_data_common_t::connect_group, anonymous_namespace{overmap_connection.cpp}::connections, get_known_connections(), LINE_OOXX, LINE_OXOX, LINE_OXXO, LINE_OXXX, LINE_XOOX, LINE_XOXO, LINE_XOXX, LINE_XXOO, LINE_XXOX, LINE_XXXO, LINE_XXXX, int_id< T >::obj(), map_data_common_t::symbol(), and ter().

Referenced by draw_from_above(), and draw_maptile().

◆ disarm_trap()

void map::disarm_trap ( const tripoint p)
Perception increases chance of disarming trap Dexterity increases chance of disarming trap Traps increases chance of disarming trap

Definition at line 5336 of file map.cpp.

5337{
5338 const trap &tr = tr_at( p );
5339 if( tr.is_null() ) {
5340 debugmsg( "Tried to disarm a trap where there was none (%d %d %d)", p.x, p.y, p.z );
5341 return;
5342 }
5343
5344 const int tSkillLevel = g->u.get_skill_level( skill_traps );
5345 const int diff = tr.get_difficulty();
5346 int roll = rng( tSkillLevel, 4 * tSkillLevel );
5347
5348 // Some traps are not actual traps. Skip the rolls, different message and give the option to grab it right away.
5349 if( tr.get_avoidance() == 0 && tr.get_difficulty() == 0 ) {
5350 add_msg( _( "The %s is taken down." ), tr.name() );
5351 tr.on_disarmed( *this, p );
5352 return;
5353 }
5354
5355 ///\EFFECT_PER increases chance of disarming trap
5356
5357 ///\EFFECT_DEX increases chance of disarming trap
5358
5359 ///\EFFECT_TRAPS increases chance of disarming trap
5360 while( ( rng( 5, 20 ) < g->u.per_cur || rng( 1, 20 ) < g->u.dex_cur ) && roll < 50 ) {
5361 roll++;
5362 }
5363 if( roll >= diff ) {
5364 add_msg( _( "You disarm the trap!" ) );
5365 const int morale_buff = tr.get_avoidance() * 0.4 + tr.get_difficulty() + rng( 0, 4 );
5366 g->u.rem_morale( MORALE_FAILURE );
5367 g->u.add_morale( MORALE_ACCOMPLISHMENT, morale_buff, 40 );
5368 tr.on_disarmed( *this, p );
5369 if( diff > 1.25 * tSkillLevel ) { // failure might have set off trap
5370 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5371 }
5372 } else if( roll >= diff * .8 ) {
5373 add_msg( _( "You fail to disarm the trap." ) );
5374 const int morale_debuff = -rng( 6, 18 );
5375 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5376 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5377 if( diff > 1.25 * tSkillLevel ) {
5378 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5379 }
5380 } else {
5381 add_msg( m_bad, _( "You fail to disarm the trap, and you set it off!" ) );
5382 const int morale_debuff = -rng( 12, 24 );
5383 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5384 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5385 tr.trigger( p, &g->u );
5386 if( diff - roll <= 6 ) {
5387 // Give xp for failing, but not if we failed terribly (in which
5388 // case the trap may not be disarmable).
5389 g->u.practice( skill_traps, 2 * diff );
5390 }
5391 }
5392}
static const skill_id skill_traps("traps")
void add_msg(std::string msg)
Definition: messages.cpp:910
const morale_type MORALE_FAILURE("morale_failure")
const morale_type MORALE_ACCOMPLISHMENT("morale_accomplishment")
Definition: trap.h:86
std::string name() const
Definition: trap.cpp:177
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
void trigger(const tripoint &pos, Creature *creature=nullptr, item *item=nullptr) const
Trigger trap effects.
Definition: trap.cpp:232
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
void on_disarmed(map &m, const tripoint &p) const
Called when a trap at the given point in the map has been disarmed.
Definition: trap.cpp:260
int get_difficulty() const
This is used when disarming the trap.
Definition: trap.h:152

References _, add_msg(), debugmsg, g, trap::get_avoidance(), trap::get_difficulty(), trap::is_null(), m_bad, MORALE_ACCOMPLISHMENT, MORALE_FAILURE, trap::name(), trap::on_disarmed(), rng(), skill_traps, tr_at(), trap::trigger(), tripoint::x, tripoint::y, and tripoint::z.

◆ disp_name()

std::string map::disp_name ( const tripoint p)

Definition at line 1395 of file map.cpp.

1396{
1397 return string_format( _( "the %s" ), name( p ) );
1398}

References _, name(), and string_format().

◆ displace_vehicle()

bool map::displace_vehicle ( vehicle veh,
const tripoint dp 
)

Definition at line 1184 of file map.cpp.

1185{
1186 const tripoint src = veh.global_pos3();
1187
1188 tripoint dst = src + dp;
1189
1190 if( !inbounds( src ) ) {
1191 add_msg( m_debug, "map::displace_vehicle: coordinates out of bounds %d,%d,%d->%d,%d,%d",
1192 src.x, src.y, src.z, dst.x, dst.y, dst.z );
1193 return false;
1194 }
1195
1196 point src_offset;
1197 point dst_offset;
1198 submap *src_submap = get_submap_at( src, src_offset );
1199 submap *dst_submap = get_submap_at( dst, dst_offset );
1200 std::set<int> smzs;
1201
1202 // first, let's find our position in current vehicles vector
1203 size_t our_i = 0;
1204 bool found = false;
1205 for( auto &smap : grid ) {
1206 for( size_t i = 0; i < smap->vehicles.size(); i++ ) {
1207 if( smap->vehicles[i].get() == &veh ) {
1208 our_i = i;
1209 src_submap = smap;
1210 found = true;
1211 break;
1212 }
1213 }
1214 if( found ) {
1215 break;
1216 }
1217 }
1218
1219 if( !found ) {
1220 add_msg( m_debug, "displace_vehicle [%s] failed", veh.name );
1221 return false;
1222 }
1223
1224 // move the vehicle
1225 // don't let it go off grid
1226 if( !inbounds( dst ) ) {
1227 veh.stop();
1228 // Silent debug
1229 dbg( DL::Error ) << "map:displace_vehicle: Stopping vehicle, displaced dp=" << dp;
1230 return true;
1231 }
1232
1233 // Need old coordinates to check for remote control
1234 const bool remote = veh.remote_controlled( g->u );
1235
1236 // record every passenger and pet inside
1237 std::vector<rider_data> riders = veh.get_riders();
1238
1239 bool need_update = false;
1240 bool z_change = false;
1241 int z_to = 0;
1242 // Move passengers and pets
1243 bool complete = false;
1244 // loop until everyone has moved or for each passenger
1245 for( size_t i = 0; !complete && i < riders.size(); i++ ) {
1246 complete = true;
1247 for( rider_data &r : riders ) {
1248 if( r.moved ) {
1249 continue;
1250 }
1251 const int prt = r.prt;
1252
1253 Creature *psg = r.psg;
1254 const tripoint part_pos = veh.global_part_pos3( prt );
1255 if( psg == nullptr ) {
1256 debugmsg( "Empty passenger for part #%d at %d,%d,%d player at %d,%d,%d?",
1257 prt, part_pos.x, part_pos.y, part_pos.z,
1258 g->u.posx(), g->u.posy(), g->u.posz() );
1260 r.moved = true;
1261 continue;
1262 }
1263
1264 if( psg->pos() != part_pos ) {
1265 add_msg( m_debug, "Part/passenger position mismatch: part #%d at %d,%d,%d "
1266 "passenger at %d,%d,%d", prt, part_pos.x, part_pos.y, part_pos.z,
1267 psg->posx(), psg->posy(), psg->posz() );
1268 }
1269 const vehicle_part &veh_part = veh.part( prt );
1270
1271 tripoint next_pos = veh_part.precalc[1];
1272
1273 // Place passenger on the new part location
1274 tripoint psgp( dst + next_pos );
1275 // someone is in the way so try again
1276 if( g->critter_at( psgp ) ) {
1277 complete = false;
1278 continue;
1279 }
1280 if( psg->is_avatar() ) {
1281 // If passenger is you, we need to update the map
1282 need_update = true;
1283 z_change = psgp.z != part_pos.z;
1284 z_to = psgp.z;
1285 }
1286
1287 psg->setpos( psgp );
1288 r.moved = true;
1289 }
1290 }
1291
1292 veh.shed_loose_parts();
1293 smzs = veh.advance_precalc_mounts( dst_offset, src );
1294 if( src_submap != dst_submap ) {
1295 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
1296 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
1297 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
1298 src_submap->vehicles.erase( src_submap_veh_it );
1299 dst_submap->is_uniform = false;
1301 }
1302 if( need_update ) {
1303 g->update_map( g->u );
1304 }
1305 add_vehicle_to_cache( &veh );
1306
1307 if( z_change || src.z != dst.z ) {
1308 if( z_change ) {
1309 g->vertical_shift( z_to );
1310 // vertical moves can flush the caches, so make sure we're still in the cache
1311 add_vehicle_to_cache( &veh );
1312 }
1313 update_vehicle_list( dst_submap, dst.z );
1314 // delete the vehicle from the source z-level vehicle cache set if it is no longer on
1315 // that z-level
1316 if( src.z != dst.z ) {
1317 level_cache &ch2 = get_cache( src.z );
1318 for( const vehicle *elem : ch2.vehicle_list ) {
1319 if( elem == &veh ) {
1320 ch2.vehicle_list.erase( &veh );
1321 ch2.zone_vehicles.erase( &veh );
1322 break;
1323 }
1324 }
1325 }
1327 }
1328
1329 if( remote ) {
1330 // Has to be after update_map or coordinates won't be valid
1331 g->setremoteveh( &veh );
1332 }
1333
1334 //
1335 //global positions of vehicle loot zones have changed.
1336 veh.zones_dirty = true;
1337
1338 for( int vsmz : smzs ) {
1339 on_vehicle_moved( dst.z + vsmz );
1340 }
1341 return true;
1342}
virtual int posy() const =0
virtual int posz() const =0
virtual void setpos(const tripoint &pos)=0
virtual bool is_avatar() const
Definition: creature.h:95
virtual int posx() const =0
void on_vehicle_moved(int smz)
Callback invoked when a vehicle has moved.
Definition: map.cpp:465
void update_vehicle_list(const submap *to, int zlev)
Definition: map.cpp:400
tripoint global_pos3() const
Definition: vehicle.cpp:3283
bool check_is_heli_landed()
std::set< int > advance_precalc_mounts(point new_pos, const tripoint &src)
Definition: vehicle.cpp:7120
void shed_loose_parts()
Definition: vehicle.cpp:6280
std::vector< rider_data > get_riders() const
Definition: vehicle.cpp:3240
void stop(bool update_cache=true)
bool remote_controlled(const Character &p) const
Definition: vehicle.cpp:299
void set_submap_moved(const tripoint &p)
Update the submap coordinates and update the tracker info in the overmap (if enabled).
Definition: vehicle.cpp:3298
bool zones_dirty
Definition: vehicle.h:1739
@ m_debug
Definition: enums.h:271
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle_part.h:24
std::array< tripoint, 2 > precalc
mount translated to face.dir [0] and turn_dir [1]
Definition: vehicle_part.h:210
int remove_flag(const int flag) noexcept
Definition: vehicle_part.h:53

References add_msg(), add_vehicle_to_cache(), vehicle::advance_precalc_mounts(), vehicle::check_is_heli_landed(), dbg, debugmsg, Error, g, get_cache(), vehicle::get_riders(), get_submap_at(), vehicle::global_part_pos3(), vehicle::global_pos3(), grid, inbounds(), invalidate_max_populated_zlev(), Creature::is_avatar(), submap::is_uniform, m_debug, avatar_action::move(), vehicle::name, on_vehicle_moved(), vehicle::part(), vehicle_part::passenger_flag, Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::precalc, vehicle::remote_controlled(), vehicle_part::remove_flag(), SEEX, SEEY, vehicle::set_submap_moved(), Creature::setpos(), vehicle::shed_loose_parts(), vehicle::stop(), update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, level_cache::zone_vehicles, and vehicle::zones_dirty.

Referenced by game::grabbed_veh_move(), and move_vehicle().

◆ displace_water()

bool map::displace_water ( const tripoint dp)

Definition at line 1344 of file map.cpp.

1345{
1346 // Check for shallow water
1347 if( has_flag( "SWIMMABLE", p ) && !has_flag( TFLAG_DEEP_WATER, p ) ) {
1348 int dis_places = 0;
1349 int sel_place = 0;
1350 for( int pass = 0; pass < 2; pass++ ) {
1351 // we do 2 passes.
1352 // first, count how many non-water places around
1353 // then choose one within count and fill it with water on second pass
1354 if( pass != 0 ) {
1355 sel_place = rng( 0, dis_places - 1 );
1356 dis_places = 0;
1357 }
1358 for( const tripoint &temp : points_in_radius( p, 1 ) ) {
1359 if( temp != p
1360 || impassable_ter_furn( temp )
1361 || has_flag( TFLAG_DEEP_WATER, temp ) ) {
1362 continue;
1363 }
1364 ter_id ter0 = ter( temp );
1365 if( ter0 == t_water_sh ||
1366 ter0 == t_water_dp || ter0 == t_water_moving_sh || ter0 == t_water_moving_dp ) {
1367 continue;
1368 }
1369 if( pass != 0 && dis_places == sel_place ) {
1370 ter_set( temp, t_water_sh );
1371 ter_set( temp, t_dirt );
1372 return true;
1373 }
1374
1375 dis_places++;
1376 }
1377 }
1378 }
1379 return false;
1380}
ter_id t_water_moving_dp
Definition: mapdata.cpp:696
ter_id t_water_moving_sh
Definition: mapdata.cpp:696
ter_id t_water_dp
Definition: mapdata.cpp:696
ter_id t_water_sh
Definition: mapdata.cpp:696

References has_flag(), impassable_ter_furn(), points_in_radius(), rng(), t_dirt, t_water_dp, t_water_moving_dp, t_water_moving_sh, t_water_sh, ter(), ter_set(), and TFLAG_DEEP_WATER.

Referenced by move_vehicle().

◆ do_vehicle_caching()

void map::do_vehicle_caching ( int  z)

Definition at line 8345 of file map.cpp.

8346{
8347 level_cache &ch = get_cache( z );
8348 for( vehicle *v : ch.vehicle_list ) {
8349 for( const vpart_reference &vp : v->get_all_parts() ) {
8350 const tripoint &part_pos = v->global_part_pos3( vp.part() );
8351 if( !inbounds( part_pos.xy() ) || vp.part().removed ) {
8352 continue;
8353 }
8354 vehicle_caching_internal( get_cache( part_pos.z ), vp, v );
8355 if( part_pos.z < OVERMAP_HEIGHT ) {
8356 vehicle_caching_internal_above( get_cache( part_pos.z + 1 ), vp, v );
8357 }
8358 }
8359 }
8360}
static void vehicle_caching_internal_above(level_cache &zch_above, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8336
static void vehicle_caching_internal(level_cache &zch, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8269

References vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), OVERMAP_HEIGHT, vehicle_caching_internal(), vehicle_caching_internal_above(), level_cache::vehicle_list, tripoint::xy(), and tripoint::z.

Referenced by build_map_cache().

◆ dont_draw_lower_floor()

bool map::dont_draw_lower_floor ( const tripoint p)

Definition at line 5999 of file map.cpp.

6000{
6001 return !zlevels || p.z <= -OVERMAP_DEPTH ||
6003}
@ TFLAG_Z_TRANSPARENT
Definition: mapdata.h:322

References has_flag(), OVERMAP_DEPTH, TFLAG_NO_FLOOR, TFLAG_Z_TRANSPARENT, tripoint::z, and zlevels.

◆ draw()

void map::draw ( const catacurses::window w,
const tripoint center 
)

Draw a visible part of the map into w.

This method uses g->u.posx()/posy() for visibility calculations, so it can not be used for anything but the player's viewport. Likewise, only g->m and maps with equivalent coordinates can be used, as other maps would have coordinate systems incompatible with g->u.posx()

Parameters
wWindow we are drawing in
centerThe coordinate of the center of the viewport, this can be different from the player coordinate.

Definition at line 5840 of file map.cpp.

5841{
5842 // We only need to draw anything if we're not in tiles mode.
5843 if( is_draw_tiles_mode() ) {
5844 return;
5845 }
5846
5847 g->reset_light_level();
5848
5851
5852 const auto &visibility_cache = get_cache_ref( center.z ).visibility_cache;
5853
5854 int wnd_h = getmaxy( w );
5855 int wnd_w = getmaxx( w );
5856 const tripoint offs = center - tripoint( wnd_w / 2, wnd_h / 2, 0 );
5857
5858 // Map memory should be at least the size of the view range
5859 // so that new tiles can be memorized, and at least the size of the terminal
5860 // since displayed area may be bigger than view range.
5861 const point min_mm_reg = point(
5862 std::min( 0, offs.x ),
5863 std::min( 0, offs.y )
5864 );
5865 const point max_mm_reg = point(
5866 std::max( MAPSIZE_X, offs.x + wnd_w ),
5867 std::max( MAPSIZE_Y, offs.y + wnd_h )
5868 );
5869 g->u.prepare_map_memory_region(
5870 g->m.getabs( tripoint( min_mm_reg, center.z ) ),
5871 g->m.getabs( tripoint( max_mm_reg, center.z ) )
5872 );
5873
5874 const auto draw_background = [&]( const tripoint & p ) {
5875 int sym = ' ';
5876 nc_color col = c_black;
5877 if( has_memory_at( p ) ) {
5878 sym = get_memory_at( p );
5879 col = c_brown;
5880 }
5881 wputch( w, col, sym );
5882 };
5883
5884 const auto draw_vision_effect = [&]( const visibility_type vis ) -> bool {
5885 int sym = '#';
5886 nc_color col;
5887 switch( vis )
5888 {
5889 case VIS_LIT:
5890 // can only tell that this square is bright
5891 col = c_light_gray;
5892 break;
5893 case VIS_BOOMER:
5894 col = c_pink;
5895 break;
5896 case VIS_BOOMER_DARK:
5897 col = c_magenta;
5898 break;
5899 default:
5900 return false;
5901 }
5902 wputch( w, col, sym );
5903 return true;
5904 };
5905
5906 drawsq_params params = drawsq_params().memorize( true );
5907 for( int wy = 0; wy < wnd_h; wy++ ) {
5908 for( int wx = 0; wx < wnd_w; wx++ ) {
5909 wmove( w, point( wx, wy ) );
5910 const tripoint p = offs + tripoint( wx, wy, 0 );
5911 if( !inbounds( p ) ) {
5912 draw_background( p );
5913 continue;
5914 }
5915
5916 const lit_level lighting = visibility_cache[p.x][p.y];
5917 const visibility_type vis = get_visibility( lighting, cache );
5918
5919 if( draw_vision_effect( vis ) ) {
5920 continue;
5921 }
5922
5923 if( vis == VIS_HIDDEN || vis == VIS_DARK ) {
5924 draw_background( p );
5925 continue;
5926 }
5927
5928 const maptile curr_maptile = maptile_at_internal( p );
5929 params
5930 .low_light( lighting == lit_level::LOW )
5931 .bright_light( lighting == lit_level::BRIGHT );
5932 if( draw_maptile( w, p, curr_maptile, params ) ) {
5933 continue;
5934 }
5935 const maptile tile_below = maptile_at_internal( p - tripoint_above );
5936 draw_from_above( w, tripoint( p.xy(), p.z - 1 ), tile_below, params );
5937 }
5938 }
5939
5940 // Memorize off-screen tiles
5941 half_open_rectangle<point> display( offs.xy(), offs.xy() + point( wnd_w, wnd_h ) );
5942 drawsq_params mm_params = drawsq_params().memorize( true ).output( false );
5943 for( int y = 0; y < MAPSIZE_Y; y++ ) {
5944 for( int x = 0; x < MAPSIZE_X; x++ ) {
5945 const tripoint p( x, y, center.z );
5946 if( display.contains( p.xy() ) ) {
5947 // Have been memorized during display loop
5948 continue;
5949 }
5950
5951 const lit_level lighting = visibility_cache[p.x][p.y];
5952 const visibility_type vis = get_visibility( lighting, cache );
5953
5954 if( vis != VIS_CLEAR ) {
5955 continue;
5956 }
5957
5958 const maptile curr_maptile = maptile_at_internal( p );
5959 mm_params
5960 .low_light( lighting == lit_level::LOW )
5961 .bright_light( lighting == lit_level::BRIGHT );
5962
5963 draw_maptile( w, p, curr_maptile, mm_params );
5964 }
5965 }
5966}
bool draw_maptile(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Internal version of the drawsq.
Definition: map.cpp:6005
visibility_type get_visibility(lit_level ll, const visibility_variables &cache) const
Definition: map.cpp:5790
void draw_from_above(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Draws the tile as seen from above.
Definition: map.cpp:6196
const visibility_variables & get_visibility_variables_cache() const
Definition: map.cpp:5785
void update_visibility_cache(int zlev)
Definition: map.cpp:5736
maptile maptile_at_internal(const tripoint &p) const
Definition: map.cpp:279
#define c_light_gray
Definition: color.h:19
#define c_black
Definition: color.h:17
#define c_magenta
Definition: color.h:25
#define c_brown
Definition: color.h:26
#define c_pink
Definition: color.h:31
visibility_type
Definition: enums.h:57
@ VIS_CLEAR
Definition: enums.h:59
@ VIS_BOOMER
Definition: enums.h:61
@ VIS_DARK
Definition: enums.h:62
@ VIS_BOOMER_DARK
Definition: enums.h:63
@ VIS_HIDDEN
Definition: enums.h:58
@ VIS_LIT
Definition: enums.h:60
lit_level
Definition: lightmap.h:43
static bool has_memory_at(const tripoint &p)
Definition: map.cpp:5823
static int get_memory_at(const tripoint &p)
Definition: map.cpp:5832
void wmove(const window &win, point p)
Definition: ncurses_def.cpp:98
int getmaxx(const window &win)
Definition: ncurses_def.cpp:58
int getmaxy(const window &win)
Definition: ncurses_def.cpp:63
static tripoint_abs_omt display(const tripoint_abs_omt &orig, const draw_data_t &data=draw_data_t())
bool is_draw_tiles_mode()
Check whether we're in tile drawing mode.
Definition: output.cpp:2075
void wputch(const catacurses::window &w, nc_color FG, int ch)
Definition: output.cpp:470
static constexpr tripoint tripoint_above
Definition: point.h:280
Draw parameters used by map::drawsq() and similar methods.
Definition: map.h:180
constexpr drawsq_params & bright_light(bool v)
Whether tile is in bright light.
Definition: map.h:240
constexpr drawsq_params & output(bool v)
HACK: Whether the tile should be printed.
Definition: map.h:269
constexpr drawsq_params & memorize(bool v)
Whether the tile should be memorized.
Definition: map.h:254
constexpr drawsq_params & low_light(bool v)
Whether tile is low light, and should be drawn with muted color.
Definition: map.h:226
lit_level visibility_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:350
A wrapper for a submap point.
Definition: submap.h:238

References BRIGHT, drawsq_params::bright_light(), c_black, c_brown, c_light_gray, c_magenta, c_pink, center, overmap_ui::display(), draw_from_above(), draw_maptile(), g, get_cache_ref(), get_memory_at(), get_visibility(), get_visibility_variables_cache(), catacurses::getmaxx(), catacurses::getmaxy(), has_memory_at(), inbounds(), is_draw_tiles_mode(), LOW, drawsq_params::low_light(), MAPSIZE_X, MAPSIZE_Y, maptile_at_internal(), drawsq_params::memorize(), drawsq_params::output(), tripoint_above, update_visibility_cache(), VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, VIS_LIT, level_cache::visibility_cache, catacurses::wmove(), wputch(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by advanced_inventory::draw_minimap(), and game::draw_ter().

◆ draw_anthill()

void map::draw_anthill ( mapgendata dat)
protected

Definition at line 4864 of file mapgen.cpp.

4865{
4866 const oter_id &terrain_type = dat.terrain_type();
4867 if( terrain_type == "anthill" || terrain_type == "acid_anthill" ) {
4868 for( int i = 0; i < SEEX * 2; i++ ) {
4869 for( int j = 0; j < SEEY * 2; j++ ) {
4870 if( i < 8 || j < 8 || i > SEEX * 2 - 9 || j > SEEY * 2 - 9 ) {
4871 ter_set( point( i, j ), dat.groundcover() );
4872 } else if( ( i == 11 || i == 12 ) && ( j == 11 || j == 12 ) ) {
4873 ter_set( point( i, j ), t_slope_down );
4874 } else {
4875 ter_set( point( i, j ), t_dirtmound );
4876 }
4877 }
4878 }
4879 }
4880}
const oter_id & terrain_type() const
Definition: mapgendata.h:87
ter_id groundcover()
Definition: mapgendata.cpp:141
ter_id t_slope_down
Definition: mapdata.cpp:721
ter_id t_dirtmound
Definition: mapdata.cpp:628

References mapgendata::groundcover(), SEEX, SEEY, t_dirtmound, t_slope_down, ter_set(), and mapgendata::terrain_type().

Referenced by draw_map().

◆ draw_circle_furn()

void map::draw_circle_furn ( const furn_id type,
point  p,
int  rad 
)

Definition at line 8596 of file map.cpp.

8597{
8598 draw_circle( [this, type]( point q ) {
8599 this->furn_set( q, type );
8600 }, p, rad );
8601}
void draw_circle(std::function< void(point)>set, const rl_vec2d &p, double rad)

References draw_circle(), furn_set(), rad, and type.

Referenced by circle_furn().

◆ draw_circle_ter() [1/2]

void map::draw_circle_ter ( const ter_id type,
const rl_vec2d p,
double  rad 
)

Definition at line 8582 of file map.cpp.

8583{
8584 draw_circle( [this, type]( point q ) {
8585 this->ter_set( q, type );
8586 }, p, rad );
8587}

References draw_circle(), rad, ter_set(), and type.

Referenced by circle().

◆ draw_circle_ter() [2/2]

void map::draw_circle_ter ( const ter_id type,
point  p,
int  rad 
)

Definition at line 8589 of file map.cpp.

8590{
8591 draw_circle( [this, type]( point q ) {
8592 this->ter_set( q, type );
8593 }, p, rad );
8594}

References draw_circle(), rad, ter_set(), and type.

◆ draw_connections()

void map::draw_connections ( mapgendata dat)
protected

Definition at line 5074 of file mapgen.cpp.

5075{
5076 const oter_id &terrain_type = dat.terrain_type();
5077 if( is_ot_match( "subway", terrain_type,
5078 ot_match_type::type ) ) { // FUUUUU it's IF ELIF ELIF ELIF's mini-me =[
5079 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) &&
5080 !connects_to( terrain_type, 0 ) ) {
5081 if( connects_to( dat.north(), 2 ) ) {
5082 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5083 for( int j = 0; j < SEEY; j++ ) {
5084 ter_set( point( i, j ), t_sewage );
5085 }
5086 }
5087 } else {
5088 for( int j = 0; j < 3; j++ ) {
5089 ter_set( point( SEEX, j ), t_rock_floor );
5090 ter_set( point( SEEX - 1, j ), t_rock_floor );
5091 }
5092 ter_set( point( SEEX, 3 ), t_door_metal_c );
5093 ter_set( point( SEEX - 1, 3 ), t_door_metal_c );
5094 }
5095 }
5096 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) &&
5097 !connects_to( terrain_type, 1 ) ) {
5098 if( connects_to( dat.east(), 3 ) ) {
5099 for( int i = SEEX; i < SEEX * 2; i++ ) {
5100 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5101 ter_set( point( i, j ), t_sewage );
5102 }
5103 }
5104 } else {
5105 for( int i = SEEX * 2 - 3; i < SEEX * 2; i++ ) {
5106 ter_set( point( i, SEEY ), t_rock_floor );
5107 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5108 }
5109 ter_set( point( SEEX * 2 - 4, SEEY ), t_door_metal_c );
5110 ter_set( point( SEEX * 2 - 4, SEEY - 1 ), t_door_metal_c );
5111 }
5112 }
5113 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) &&
5114 !connects_to( terrain_type, 2 ) ) {
5115 if( connects_to( dat.south(), 0 ) ) {
5116 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5117 for( int j = SEEY; j < SEEY * 2; j++ ) {
5118 ter_set( point( i, j ), t_sewage );
5119 }
5120 }
5121 } else {
5122 for( int j = SEEY * 2 - 3; j < SEEY * 2; j++ ) {
5123 ter_set( point( SEEX, j ), t_rock_floor );
5124 ter_set( point( SEEX - 1, j ), t_rock_floor );
5125 }
5126 ter_set( point( SEEX, SEEY * 2 - 4 ), t_door_metal_c );
5127 ter_set( point( SEEX - 1, SEEY * 2 - 4 ), t_door_metal_c );
5128 }
5129 }
5130 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) &&
5131 !connects_to( terrain_type, 3 ) ) {
5132 if( connects_to( dat.west(), 1 ) ) {
5133 for( int i = 0; i < SEEX; i++ ) {
5134 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5135 ter_set( point( i, j ), t_sewage );
5136 }
5137 }
5138 } else {
5139 for( int i = 0; i < 3; i++ ) {
5140 ter_set( point( i, SEEY ), t_rock_floor );
5141 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5142 }
5143 ter_set( point( 3, SEEY ), t_door_metal_c );
5144 ter_set( point( 3, SEEY - 1 ), t_door_metal_c );
5145 }
5146 }
5147 } else if( is_ot_match( "sewer", terrain_type, ot_match_type::type ) ) {
5148 if( dat.above() == "road_nesw_manhole" ) {
5149 ter_set( point( rng( SEEX - 2, SEEX + 1 ), rng( SEEY - 2, SEEY + 1 ) ), t_ladder_up );
5150 }
5151 if( is_ot_match( "subway", dat.north(), ot_match_type::type ) &&
5152 !connects_to( terrain_type, 0 ) ) {
5153 for( int j = 0; j < SEEY - 3; j++ ) {
5154 ter_set( point( SEEX, j ), t_rock_floor );
5155 ter_set( point( SEEX - 1, j ), t_rock_floor );
5156 }
5157 ter_set( point( SEEX, SEEY - 3 ), t_door_metal_c );
5158 ter_set( point( SEEX - 1, SEEY - 3 ), t_door_metal_c );
5159 }
5160 if( is_ot_match( "subway", dat.east(), ot_match_type::type ) &&
5161 !connects_to( terrain_type, 1 ) ) {
5162 for( int i = SEEX + 3; i < SEEX * 2; i++ ) {
5163 ter_set( point( i, SEEY ), t_rock_floor );
5164 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5165 }
5166 ter_set( point( SEEX + 2, SEEY ), t_door_metal_c );
5167 ter_set( point( SEEX + 2, SEEY - 1 ), t_door_metal_c );
5168 }
5169 if( is_ot_match( "subway", dat.south(), ot_match_type::type ) &&
5170 !connects_to( terrain_type, 2 ) ) {
5171 for( int j = SEEY + 3; j < SEEY * 2; j++ ) {
5172 ter_set( point( SEEX, j ), t_rock_floor );
5173 ter_set( point( SEEX - 1, j ), t_rock_floor );
5174 }
5175 ter_set( point( SEEX, SEEY + 2 ), t_door_metal_c );
5176 ter_set( point( SEEX - 1, SEEY + 2 ), t_door_metal_c );
5177 }
5178 if( is_ot_match( "subway", dat.west(), ot_match_type::type ) &&
5179 !connects_to( terrain_type, 3 ) ) {
5180 for( int i = 0; i < SEEX - 3; i++ ) {
5181 ter_set( point( i, SEEY ), t_rock_floor );
5182 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5183 }
5184 ter_set( point( SEEX - 3, SEEY ), t_door_metal_c );
5185 ter_set( point( SEEX - 3, SEEY - 1 ), t_door_metal_c );
5186 }
5187 } else if( is_ot_match( "ants", terrain_type, ot_match_type::type ) ) {
5188 if( dat.above() == "anthill" ) {
5189 if( const auto p = random_point( *this, [this]( const tripoint & n ) {
5190 return ter( n ) == t_rock_floor;
5191 } ) ) {
5192 ter_set( *p, t_slope_up );
5193 }
5194 }
5195 }
5196
5197 // finally, any terrain with SIDEWALKS should contribute sidewalks to neighboring diagonal roads
5198 if( terrain_type->has_flag( has_sidewalk ) ) {
5199 for( int dir = 4; dir < 8; dir++ ) { // NE SE SW NW
5200 bool n_roads_nesw[4] = {};
5201 int n_num_dirs = terrain_type_to_nesw_array( oter_id( dat.t_nesw[dir] ), n_roads_nesw );
5202 // only handle diagonal neighbors
5203 if( n_num_dirs == 2 &&
5204 n_roads_nesw[( ( dir - 4 ) + 3 ) % 4] &&
5205 n_roads_nesw[( ( dir - 4 ) + 2 ) % 4] ) {
5206 // make drawing simpler by rotating the map back and forth
5207 rotate( 4 - ( dir - 4 ) );
5208 // draw a small triangle of sidewalk in the northeast corner
5209 for( int y = 0; y < 4; y++ ) {
5210 for( int x = SEEX * 2 - 4; x < SEEX * 2; x++ ) {
5211 if( x - y > SEEX * 2 - 4 ) {
5212 // TODO: more discriminating conditions
5213 if( ter( point( x, y ) ) == t_grass || ter( point( x, y ) ) == t_dirt ||
5214 ter( point( x, y ) ) == t_shrub ) {
5215 ter_set( point( x, y ), t_sidewalk );
5216 }
5217 }
5218 }
5219 }
5220 rotate( ( dir - 4 ) );
5221 }
5222 }
5223 }
5224
5226}
void rotate(int turns, bool setpos_safe=false)
Rotates this map, and all of its contents, by the specified multiple of 90 degrees.
Definition: mapgen.cpp:5636
const oter_id & above() const
Definition: mapgendata.h:131
const oter_id & north() const
Definition: mapgendata.h:107
const oter_id & west() const
Definition: mapgendata.h:116
const oter_id & south() const
Definition: mapgendata.h:113
oter_id t_nesw[8]
Definition: mapgendata.h:45
const oter_id & east() const
Definition: mapgendata.h:110
std::optional< tripoint > random_point(const map &m, const std::function< bool(const tripoint &)> &predicate)
Same as other random_point with a range enclosing all valid points of the map.
ter_id t_grass
Definition: mapdata.cpp:631
ter_id t_sewage
Definition: mapdata.cpp:697
ter_id t_slope_up
Definition: mapdata.cpp:722
ter_id t_ladder_up
Definition: mapdata.cpp:721
ter_id t_shrub
Definition: mapdata.cpp:686
ter_id t_sidewalk
Definition: mapdata.cpp:633
ter_id t_door_metal_c
Definition: mapdata.cpp:665
bool connects_to(const oter_id &there, int dir)
Definition: mapgen.cpp:5738
void resolve_regional_terrain_and_furniture(const mapgendata &dat)
int terrain_type_to_nesw_array(oter_id terrain_type, bool array[4])
@ has_sidewalk
Definition: omdata.h:90
bool is_ot_match(const std::string &name, const oter_id &oter, const ot_match_type match_type)
Determine if the provided name is a match with the provided overmap terrain based on the specified ma...
Definition: overmap.cpp:568
bool has_flag(oter_flags flag) const
Definition: omdata.h:258

References mapgendata::above(), connects_to(), mapgendata::east(), oter_t::has_flag(), has_sidewalk, is_ot_match(), mapgendata::north(), oter_id, random_point(), resolve_regional_terrain_and_furniture(), rng(), rotate(), SEEX, SEEY, mapgendata::south(), t_dirt, t_door_metal_c, t_grass, t_ladder_up, mapgendata::t_nesw, t_rock_floor, t_sewage, t_shrub, t_sidewalk, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), terrain_type_to_nesw_array(), type, and mapgendata::west().

Referenced by draw_map().

◆ draw_fill_background() [1/3]

void map::draw_fill_background ( const ter_id type)

Definition at line 8511 of file map.cpp.

8512{
8513 // Need to explicitly set caches dirty - set_ter would do it before
8518
8519 // Fill each submap rather than each tile
8520 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
8521 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
8522 auto sm = get_submap_at_grid( {gridx, gridy} );
8523 sm->is_uniform = true;
8524 sm->set_all_ter( type );
8525 }
8526 }
8527}
void set_outside_cache_dirty(const int zlev)
Definition: map.cpp:222

References abs_sub, get_submap_at_grid(), my_MAPSIZE, set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), coords::sm, type, and tripoint::z.

Referenced by fill_background(), mapgendata::fill_groundcover(), mapgen_function_json::generate(), and mapgen_forest().

◆ draw_fill_background() [2/3]

void map::draw_fill_background ( const weighted_int_list< ter_id > &  f)

Definition at line 8533 of file map.cpp.

8534{
8536}
void draw_square_ter(const ter_id &type, point p1, point p2)
Definition: map.cpp:8538

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_fill_background() [3/3]

void map::draw_fill_background ( ter_id(*)()  f)

Definition at line 8529 of file map.cpp.

8530{
8532}

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_from_above()

void map::draw_from_above ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Draws the tile as seen from above.

Definition at line 6196 of file map.cpp.

6198{
6199 static const int AUTO_WALL_PLACEHOLDER = 2; // this should never appear as a real symbol!
6200
6201 nc_color tercol = c_dark_gray;
6202 int sym = ' ';
6203
6204 const ter_t &curr_ter = curr_tile.get_ter_t();
6205 const furn_t &curr_furn = curr_tile.get_furn_t();
6206 int part_below;
6207 const vehicle *veh;
6208 if( curr_furn.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6209 sym = curr_furn.symbol();
6210 tercol = curr_furn.color();
6211 } else if( curr_furn.movecost < 0 ) {
6212 sym = '.';
6213 tercol = curr_furn.color();
6214 } else if( ( veh = veh_at_internal( p, part_below ) ) != nullptr ) {
6215 const int roof = veh->roof_at_part( part_below );
6216 const int displayed_part = roof >= 0 ? roof : part_below;
6217 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( displayed_part, true ) ) );
6218 tercol = ( roof >= 0 ||
6219 vpart_position( const_cast<vehicle &>( *veh ),
6220 part_below ).obstacle_at_part() ) ? c_light_gray : c_light_gray_cyan;
6221 } else if( curr_ter.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6222 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
6223 sym = AUTO_WALL_PLACEHOLDER;
6224 } else if( curr_ter.has_flag( TFLAG_RAMP ) ) {
6225 sym = '>';
6226 } else {
6227 sym = curr_ter.symbol();
6228 }
6229 tercol = curr_ter.color();
6230 } else if( curr_ter.movecost == 0 ) {
6231 sym = '.';
6232 tercol = curr_ter.color();
6233 } else if( !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6234 sym = '.';
6235 if( curr_ter.color() != c_cyan ) {
6236 // Need a special case here, it doesn't cyanize well
6237 tercol = cyan_background( curr_ter.color() );
6238 } else {
6239 tercol = c_black_cyan;
6240 }
6241 } else {
6242 sym = curr_ter.symbol();
6243 tercol = curr_ter.color();
6244 }
6245
6246 if( sym == AUTO_WALL_PLACEHOLDER ) {
6247 sym = determine_wall_corner( p );
6248 }
6249
6250 const auto u_vision = g->u.get_vision_modes();
6251 if( u_vision[BOOMERED] ) {
6252 tercol = c_magenta;
6253 } else if( u_vision[NV_GOGGLES] ) {
6254 tercol = params.bright_light() ? c_white : c_light_green;
6255 } else if( params.low_light() ) {
6256 tercol = c_dark_gray;
6257 } else if( u_vision[DARKNESS] ) {
6258 tercol = c_dark_gray;
6259 }
6260
6261 if( params.highlight() ) {
6262 tercol = invert_color( tercol );
6263 }
6264
6265 if( params.output() ) {
6266 wputch( w, tercol, sym );
6267 }
6268}
int determine_wall_corner(const tripoint &p) const
Definition: map.cpp:7990
vehicle * veh_at_internal(const tripoint &p, int &part_num)
Definition: map.cpp:1109
int dir_symbol(int sym) const
Definition: tileray.cpp:113
char part_sym(int p, bool exact=false) const
int roof_at_part(int p) const
Definition: vehicle.cpp:3014
tileray face
Definition: vehicle.h:1680
std::optional< vpart_reference > obstacle_at_part() const
Returns the obstacle that exists at this point of the vehicle (if any).
Definition: vehicle.cpp:2440
nc_color invert_color(const nc_color &c)
Definition: color.cpp:503
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
#define c_white
Definition: color.h:18
#define c_light_green
Definition: color.h:28
#define c_dark_gray
Definition: color.h:20
#define c_black_cyan
Definition: color.h:154
#define c_cyan
Definition: color.h:24
#define c_light_gray_cyan
Definition: color.h:156
@ TFLAG_AUTO_WALL_SYMBOL
Definition: mapdata.h:306
@ TFLAG_SEEN_FROM_ABOVE
Definition: mapdata.h:312
int special_symbol(int sym)
Definition: output.cpp:1095
constexpr drawsq_params & highlight(bool v)
Highlight the tile.
Definition: map.h:198
nc_color color() const
Definition: mapdata.cpp:558

References BOOMERED, drawsq_params::bright_light(), c_black_cyan, c_cyan, c_dark_gray, c_light_gray, c_light_gray_cyan, c_light_green, c_magenta, c_white, map_data_common_t::color(), cyan_background(), DARKNESS, determine_wall_corner(), tileray::dir_symbol(), vehicle::face, g, maptile::get_furn_t(), maptile::get_ter_t(), map_data_common_t::has_flag(), drawsq_params::highlight(), invert_color(), drawsq_params::low_light(), map_data_common_t::movecost, NV_GOGGLES, vpart_position::obstacle_at_part(), drawsq_params::output(), vehicle::part_sym(), vehicle::roof_at_part(), special_symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_SEEN_FROM_ABOVE, veh_at_internal(), and wputch().

Referenced by draw(), and drawsq().

◆ draw_lab()

void map::draw_lab ( mapgendata dat)
protected

Definition at line 3553 of file mapgen.cpp.

3554{
3555 const oter_id &terrain_type = dat.terrain_type();
3556 // To distinguish between types of labs
3557 bool ice_lab = true;
3558 bool central_lab = false;
3559 bool tower_lab = false;
3560
3561 point p2;
3562
3563 int lw = 0;
3564 int rw = 0;
3565 int tw = 0;
3566 int bw = 0;
3567
3568 if( terrain_type == "lab" || terrain_type == "lab_stairs" || terrain_type == "lab_core" ||
3569 terrain_type == "ants_lab" || terrain_type == "ants_lab_stairs" ||
3570 terrain_type == "ice_lab" || terrain_type == "ice_lab_stairs" ||
3571 terrain_type == "ice_lab_core" ||
3572 terrain_type == "central_lab" || terrain_type == "central_lab_stairs" ||
3573 terrain_type == "central_lab_core" ||
3574 terrain_type == "tower_lab" || terrain_type == "tower_lab_stairs" ) {
3575
3576 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
3577 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
3578 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
3579
3580 if( ice_lab ) {
3581 int temperature = -20 + 30 * ( dat.zlevel() );
3583 set_temperature( p2 + point( SEEX, 0 ), temperature );
3584 set_temperature( p2 + point( 0, SEEY ), temperature );
3586 }
3587
3588 // Check for adjacent sewers; used below
3589 tw = 0;
3590 rw = 0;
3591 bw = 0;
3592 lw = 0;
3593 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) && connects_to( dat.north(), 2 ) ) {
3594 tw = SOUTH_EDGE + 1;
3595 }
3596 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) && connects_to( dat.east(), 3 ) ) {
3597 rw = EAST_EDGE + 1;
3598 }
3599 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) && connects_to( dat.south(), 0 ) ) {
3600 bw = SOUTH_EDGE + 1;
3601 }
3602 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) && connects_to( dat.west(), 1 ) ) {
3603 lw = EAST_EDGE + 1;
3604 }
3605 if( dat.zlevel() == 0 ) { // We're on ground level
3606 for( int i = 0; i < SEEX * 2; i++ ) {
3607 for( int j = 0; j < SEEY * 2; j++ ) {
3608 if( i <= 1 || i >= SEEX * 2 - 2 ||
3609 ( j > 1 && j < SEEY * 2 - 2 && ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3610 ter_set( point( i, j ), t_concrete_wall );
3611 } else if( j <= 1 || j >= SEEY * 2 - 2 ) {
3612 ter_set( point( i, j ), t_concrete_wall );
3613 } else {
3614 ter_set( point( i, j ), t_floor );
3615 }
3616 }
3617 }
3618 ter_set( point( SEEX - 1, 0 ), t_door_metal_locked );
3619 ter_set( point( SEEX - 1, 1 ), t_floor );
3621 ter_set( point( SEEX, 1 ), t_floor );
3622 ter_set( point( SEEX - 2 + rng( 0, 1 ) * 3, 0 ), t_card_science );
3623 ter_set( point( SEEX - 2, SEEY ), t_door_metal_c );
3624 ter_set( point( SEEX + 1, SEEY ), t_door_metal_c );
3625 ter_set( point( SEEX - 2, SEEY - 1 ), t_door_metal_c );
3626 ter_set( point( SEEX + 1, SEEY - 1 ), t_door_metal_c );
3627 ter_set( point( SEEX - 1, SEEY * 2 - 3 ), t_stairs_down );
3628 ter_set( point( SEEX, SEEY * 2 - 3 ), t_stairs_down );
3629 science_room( this, point( 2, 2 ), point( SEEX - 3, SEEY * 2 - 3 ), dat.zlevel(), 1 );
3630 science_room( this, point( SEEX + 2, 2 ), point( SEEX * 2 - 3, SEEY * 2 - 3 ), dat.zlevel(), 3 );
3631
3632 place_spawns( GROUP_TURRET, 1, point( SEEX, 5 ), point( SEEX, 5 ), 1, true );
3633
3634 if( is_ot_match( "road", dat.east(), ot_match_type::type ) ) {
3635 rotate( 1 );
3636 } else if( is_ot_match( "road", dat.south(), ot_match_type::type ) ) {
3637 rotate( 2 );
3638 } else if( is_ot_match( "road", dat.west(), ot_match_type::type ) ) {
3639 rotate( 3 );
3640 }
3641 } else if( tw != 0 || rw != 0 || lw != 0 || bw != 0 ) { // Sewers!
3642 for( int i = 0; i < SEEX * 2; i++ ) {
3643 for( int j = 0; j < SEEY * 2; j++ ) {
3644 ter_set( point( i, j ), t_thconc_floor );
3645 if( ( ( i < lw || i > EAST_EDGE - rw ) && j > SEEY - 3 && j < SEEY + 2 ) ||
3646 ( ( j < tw || j > SOUTH_EDGE - bw ) && i > SEEX - 3 && i < SEEX + 2 ) ) {
3647 ter_set( point( i, j ), t_sewage );
3648 }
3649 if( ( i == 0 && is_ot_match( "lab", dat.east(), ot_match_type::contains ) ) || i == EAST_EDGE ) {
3650 if( ter( point( i, j ) ) == t_sewage ) {
3651 ter_set( point( i, j ), t_bars );
3652 } else if( j == SEEY - 1 || j == SEEY ) {
3653 ter_set( point( i, j ), t_door_metal_c );
3654 } else {
3655 ter_set( point( i, j ), t_concrete_wall );
3656 }
3657 } else if( ( j == 0 && is_ot_match( "lab", dat.north(), ot_match_type::contains ) ) ||
3658 j == SOUTH_EDGE ) {
3659 if( ter( point( i, j ) ) == t_sewage ) {
3660 ter_set( point( i, j ), t_bars );
3661 } else if( i == SEEX - 1 || i == SEEX ) {
3662 ter_set( point( i, j ), t_door_metal_c );
3663 } else {
3664 ter_set( point( i, j ), t_concrete_wall );
3665 }
3666 }
3667 }
3668 }
3669 } else { // We're below ground, and no sewers
3670 // Set up the boundaries of walls (connect to adjacent lab squares)
3671 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
3672 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
3673 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
3674 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
3675
3676 int boarders = 0;
3677 if( tw == 0 ) {
3678 boarders++;
3679 }
3680 if( rw == 1 ) {
3681 boarders++;
3682 }
3683 if( bw == 1 ) {
3684 boarders++;
3685 }
3686 if( lw == 0 ) {
3687 boarders++;
3688 }
3689
3690 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
3691 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
3692 const auto predicate = [this]( const tripoint & p ) {
3693 return ter( p ) == t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null();
3694 };
3695 const auto range = points_in_rectangle( { 0, 0, abs_sub.z }, { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
3696
3697 if( const auto p = random_point( range, predicate ) ) {
3698 ter_set( *p, t_stair_type );
3699 }
3700 }
3701 };
3702
3703 //A lab area with only one entrance
3704 if( boarders == 1 ) {
3705 // If you remove the usage of "lab_1side" here, remove it from mapgen_factory::get_usages above as well.
3706 if( oter_mapgen.generate( dat, "lab_1side" ) ) {
3707 if( tw == 2 ) {
3708 rotate( 2 );
3709 }
3710 if( rw == 2 ) {
3711 rotate( 1 );
3712 }
3713 if( lw == 2 ) {
3714 rotate( 3 );
3715 }
3716 } else {
3717 debugmsg( "Error: Tried to generate 1-sided lab but no lab_1side json exists." );
3718 }
3719 maybe_insert_stairs( dat.above(), t_stairs_up );
3720 maybe_insert_stairs( terrain_type, t_stairs_down );
3721 } else {
3722 const int hardcoded_4side_map_weight = 1500; // weight of all hardcoded maps.
3723 // If you remove the usage of "lab_4side" here, remove it from mapgen_factory::get_usages above as well.
3724 if( oter_mapgen.generate( dat, "lab_4side", hardcoded_4side_map_weight ) ) {
3725 // If the map template hasn't handled borders, handle them in code.
3726 // Rotated maps cannot handle borders and have to be caught in code.
3727 // We determine if a border isn't handled by checking the east-facing
3728 // border space where the door normally is -- it should be a wall or door.
3729 tripoint east_border( 23, 11, abs_sub.z );
3730 if( !has_flag_ter( "WALL", east_border ) &&
3731 !has_flag_ter( "DOOR", east_border ) ) {
3732 // TODO: create a ter_reset function that does ter_set,
3733 // furn_set, and i_clear?
3734 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3735 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3736 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass :
3738 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass :
3740 for( int i = 0; i < SEEX * 2; i++ ) {
3741 ter_set( point( 23, i ), rw_type );
3742 furn_set( point( 23, i ), f_null );
3743 i_clear( tripoint( 23, i, get_abs_sub().z ) );
3744
3745 ter_set( point( i, 23 ), bw_type );
3746 furn_set( point( i, 23 ), f_null );
3747 i_clear( tripoint( i, 23, get_abs_sub().z ) );
3748
3749 if( lw == 2 ) {
3750 ter_set( point( 0, i ), lw_type );
3751 furn_set( point( 0, i ), f_null );
3752 i_clear( tripoint( 0, i, get_abs_sub().z ) );
3753 }
3754 if( tw == 2 ) {
3755 ter_set( point( i, 0 ), tw_type );
3756 furn_set( point( i, 0 ), f_null );
3757 i_clear( tripoint( i, 0, get_abs_sub().z ) );
3758 }
3759 }
3760 if( rw != 2 ) {
3761 ter_set( point( 23, 11 ), t_door_metal_c );
3762 ter_set( point( 23, 12 ), t_door_metal_c );
3763 }
3764 if( bw != 2 ) {
3765 ter_set( point( 11, 23 ), t_door_metal_c );
3766 ter_set( point( 12, 23 ), t_door_metal_c );
3767 }
3768 }
3769
3770 maybe_insert_stairs( dat.above(), t_stairs_up );
3771 maybe_insert_stairs( terrain_type, t_stairs_down );
3772 } else { // then no json maps for lab_4side were found
3773 switch( rng( 1, 3 ) ) {
3774 case 1:
3775 // Cross shaped
3776 for( int i = 0; i < SEEX * 2; i++ ) {
3777 for( int j = 0; j < SEEY * 2; j++ ) {
3778 if( ( i < lw || i > EAST_EDGE - rw ) ||
3779 ( ( j < SEEY - 1 || j > SEEY ) &&
3780 ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3781 ter_set( point( i, j ), t_concrete_wall );
3782 } else if( ( j < tw || j > SOUTH_EDGE - bw ) ||
3783 ( ( i < SEEX - 1 || i > SEEX ) &&
3784 ( j == SEEY - 2 || j == SEEY + 1 ) ) ) {
3785 ter_set( point( i, j ), t_concrete_wall );
3786 } else {
3787 ter_set( point( i, j ), t_thconc_floor );
3788 }
3789 }
3790 }
3791 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3792 ter_set( point( rng( SEEX - 1, SEEX ), rng( SEEY - 1, SEEY ) ),
3793 t_stairs_up );
3794 }
3795 // Top left
3796 if( one_in( 2 ) ) {
3797 ter_set( point( SEEX - 2, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3798 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 1 );
3799 } else {
3801 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 2 );
3802 }
3803 // Top right
3804 if( one_in( 2 ) ) {
3805 ter_set( point( SEEX + 1, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3806 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3807 dat.zlevel(), 3 );
3808 } else {
3809 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 2 ), t_door_glass_frosted_c );
3810 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3811 dat.zlevel(), 2 );
3812 }
3813 // Bottom left
3814 if( one_in( 2 ) ) {
3816 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3817 dat.zlevel(), 0 );
3818 } else {
3819 ter_set( point( SEEX - 2, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3820 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3821 dat.zlevel(), 1 );
3822 }
3823 // Bottom right
3824 if( one_in( 2 ) ) {
3825 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 1 ), t_door_glass_frosted_c );
3826 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3827 dat.zlevel(), 0 );
3828 } else {
3829 ter_set( point( SEEX + 1, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3830 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3831 dat.zlevel(), 3 );
3832 }
3833 if( rw == 1 ) {
3836 }
3837 if( bw == 1 ) {
3840 }
3841 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) { // Stairs going down
3842 std::vector<point> stair_points;
3843 if( tw != 0 ) {
3844 stair_points.push_back( point( SEEX - 1, 2 ) );
3845 stair_points.push_back( point( SEEX - 1, 2 ) );
3846 stair_points.push_back( point( SEEX, 2 ) );
3847 stair_points.push_back( point( SEEX, 2 ) );
3848 }
3849 if( rw != 1 ) {
3850 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3851 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3852 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3853 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3854 }
3855 if( bw != 1 ) {
3856 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3857 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3858 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3859 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3860 }
3861 if( lw != 0 ) {
3862 stair_points.push_back( point( 2, SEEY - 1 ) );
3863 stair_points.push_back( point( 2, SEEY - 1 ) );
3864 stair_points.push_back( point( 2, SEEY ) );
3865 stair_points.push_back( point( 2, SEEY ) );
3866 }
3867 stair_points.push_back( point( int( SEEX / 2 ), SEEY ) );
3868 stair_points.push_back( point( int( SEEX / 2 ), SEEY - 1 ) );
3869 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY ) );
3870 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY - 1 ) );
3871 stair_points.push_back( point( SEEX, int( SEEY / 2 ) ) );
3872 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) ) );
3873 stair_points.push_back( point( SEEX, int( SEEY / 2 ) + SEEY ) );
3874 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) + SEEY ) );
3875 const point p = random_entry( stair_points );
3876 ter_set( p, t_stairs_down );
3877 }
3878
3879 break;
3880
3881 case 2:
3882 // tic-tac-toe # layout
3883 for( int i = 0; i < SEEX * 2; i++ ) {
3884 for( int j = 0; j < SEEY * 2; j++ ) {
3885 if( i < lw || i > EAST_EDGE - rw || i == SEEX - 4 ||
3886 i == SEEX + 3 ) {
3887 ter_set( point( i, j ), t_concrete_wall );
3888 } else if( j < tw || j > SOUTH_EDGE - bw || j == SEEY - 4 ||
3889 j == SEEY + 3 ) {
3890 ter_set( point( i, j ), t_concrete_wall );
3891 } else {
3892 ter_set( point( i, j ), t_thconc_floor );
3893 }
3894 }
3895 }
3896 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3897 ter_set( point( SEEX - 1, SEEY - 1 ), t_stairs_up );
3898 ter_set( point( SEEX, SEEY - 1 ), t_stairs_up );
3899 ter_set( point( SEEX - 1, SEEY ), t_stairs_up );
3901 }
3902 ter_set( point( SEEX - rng( 0, 1 ), SEEY - 4 ), t_door_glass_frosted_c );
3903 ter_set( point( SEEX - rng( 0, 1 ), SEEY + 3 ), t_door_glass_frosted_c );
3904 ter_set( point( SEEX - 4, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3905 ter_set( point( SEEX + 3, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3906 ter_set( point( SEEX - 4, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3907 ter_set( point( SEEX + 3, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3910 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 4 ), t_door_glass_frosted_c );
3911 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 3 ), t_door_glass_frosted_c );
3912 ter_set( point( SEEX - 4, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3913 ter_set( point( SEEX + 3, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3914 science_room( this, point( lw, tw ), point( SEEX - 5, SEEY - 5 ), dat.zlevel(),
3915 rng( 1, 2 ) );
3916 science_room( this, point( SEEX - 3, tw ), point( SEEX + 2, SEEY - 5 ), dat.zlevel(), 2 );
3917 science_room( this, point( SEEX + 4, tw ), point( EAST_EDGE - rw, SEEY - 5 ),
3918 dat.zlevel(), rng( 2, 3 ) );
3919 science_room( this, point( lw, SEEY - 3 ), point( SEEX - 5, SEEY + 2 ), dat.zlevel(), 1 );
3920 science_room( this, point( SEEX + 4, SEEY - 3 ), point( EAST_EDGE - rw, SEEY + 2 ),
3921 dat.zlevel(), 3 );
3922 science_room( this, point( lw, SEEY + 4 ), point( SEEX - 5, SOUTH_EDGE - bw ),
3923 dat.zlevel(), rng( 0, 1 ) );
3924 science_room( this, point( SEEX - 3, SEEY + 4 ), point( SEEX + 2, SOUTH_EDGE - bw ),
3925 dat.zlevel(), 0 );
3926 science_room( this, point( SEEX + 4, SEEX + 4 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3927 dat.zlevel(), 3 * rng( 0, 1 ) );
3928 if( rw == 1 ) {
3931 }
3932 if( bw == 1 ) {
3935 }
3936 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) {
3937 ter_set( point( SEEX - 3 + 5 * rng( 0, 1 ), SEEY - 3 + 5 * rng( 0, 1 ) ),
3938 t_stairs_down );
3939 }
3940 break;
3941
3942 case 3:
3943 // Big room
3944 for( int i = 0; i < SEEX * 2; i++ ) {
3945 for( int j = 0; j < SEEY * 2; j++ ) {
3946 if( i < lw || i >= EAST_EDGE - rw ) {
3947 ter_set( point( i, j ), t_concrete_wall );
3948 } else if( j < tw || j >= SOUTH_EDGE - bw ) {
3949 ter_set( point( i, j ), t_concrete_wall );
3950 } else {
3951 ter_set( point( i, j ), t_thconc_floor );
3952 }
3953 }
3954 }
3955 science_room( this, point( lw, tw ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3956 dat.zlevel(), rng( 0, 3 ) );
3957
3958 if( rw == 1 ) {
3961 }
3962 if( bw == 1 ) {
3965 }
3966 maybe_insert_stairs( dat.above(), t_stairs_up );
3967 maybe_insert_stairs( terrain_type, t_stairs_down );
3968 break;
3969 }
3970 } // endif use_hardcoded_4side_map
3971 } // end 1 vs 4 sides
3972 } // end aboveground vs belowground
3973
3974 // Ants will totally wreck up the place
3975 if( is_ot_match( "ants", terrain_type, ot_match_type::contains ) ) {
3976 for( int i = 0; i < SEEX * 2; i++ ) {
3977 for( int j = 0; j < SEEY * 2; j++ ) {
3978 // Carve out a diamond area that covers 2 spaces on each edge.
3979 if( i + j > 10 && i + j < 36 && std::abs( i - j ) < 13 ) {
3980 // Doors and walls get sometimes destroyed:
3981 // 100% at the edge, usually in a central cross, occasionally elsewhere.
3982 if( ( has_flag_ter( "DOOR", point( i, j ) ) || has_flag_ter( "WALL", point( i, j ) ) ) ) {
3983 if( ( i == 0 || j == 0 || i == 23 || j == 23 ) ||
3984 ( !one_in( 3 ) && ( i == 11 || i == 12 || j == 11 || j == 12 ) ) ||
3985 one_in( 4 ) ) {
3986 // bash and usually remove the rubble.
3987 make_rubble( { i, j, abs_sub.z } );
3988 ter_set( point( i, j ), t_rock_floor );
3989 if( !one_in( 3 ) ) {
3990 furn_set( point( i, j ), f_null );
3991 }
3992 }
3993 // and then randomly destroy 5% of the remaining nonstairs.
3994 } else if( one_in( 20 ) &&
3995 !has_flag_ter( "GOES_DOWN", p2 ) &&
3996 !has_flag_ter( "GOES_UP", p2 ) ) {
3997 destroy( { i, j, abs_sub.z } );
3998 // bashed squares can create dirt & floors, but we want rock floors.
3999 if( t_dirt == ter( point( i, j ) ) || t_floor == ter( point( i, j ) ) ) {
4000 ter_set( point( i, j ), t_rock_floor );
4001 }
4002 }
4003 }
4004 }
4005 }
4006 }
4007
4008 // Slimes pretty much wreck up the place, too, but only underground
4009 tw = ( dat.north() == "slimepit" ? SEEY : 0 );
4010 rw = ( dat.east() == "slimepit" ? SEEX + 1 : 0 );
4011 bw = ( dat.south() == "slimepit" ? SEEY + 1 : 0 );
4012 lw = ( dat.west() == "slimepit" ? SEEX : 0 );
4013 if( tw != 0 || rw != 0 || bw != 0 || lw != 0 ) {
4014 for( int i = 0; i < SEEX * 2; i++ ) {
4015 for( int j = 0; j < SEEY * 2; j++ ) {
4016 if( ( ( j <= tw || i >= rw ) && i >= j && ( EAST_EDGE - i ) <= j ) ||
4017 ( ( j >= bw || i <= lw ) && i <= j && ( SOUTH_EDGE - j ) <= i ) ) {
4018 if( one_in( 5 ) ) {
4020 t_slime );
4021 } else if( !one_in( 5 ) ) {
4022 ter_set( point( i, j ), t_slime );
4023 }
4024 }
4025 }
4026 }
4027 }
4028
4029 int light_odds = 0;
4030 // central labs are always fully lit, other labs have half chance of some lights.
4031 if( central_lab ) {
4032 light_odds = 1;
4033 } else if( one_in( 2 ) ) {
4034 // Create a spread of densities, from all possible lights on, to 1/3, ...
4035 // to ~1 per segment.
4036 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4037 }
4038 if( light_odds > 0 ) {
4039 for( int i = 0; i < SEEX * 2; i++ ) {
4040 for( int j = 0; j < SEEY * 2; j++ ) {
4041 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4042 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4044 }
4045 }
4046 }
4047 }
4048 }
4049
4050 if( tower_lab ) {
4052 }
4053
4054 // Lab special effects.
4055 if( one_in( 10 ) ) {
4056 switch( rng( 1, 7 ) ) {
4057 // full flooding/sewage
4058 case 1: {
4059 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4060 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4061 // don't flood if stairs because the floor below will not be flooded.
4062 // don't flood if ice lab because there's no mechanic for freezing
4063 // liquid floors.
4064 break;
4065 }
4066 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4067 for( int i = 0; i < EAST_EDGE; i++ ) {
4068 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4069 // We spare some terrain to make it look better visually.
4070 if( !one_in( 10 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4071 t_strconc_floor == ter( point( i, j ) ) ||
4072 t_thconc_floor_olight == ter( point( i, j ) ) ) ) {
4073 ter_set( point( i, j ), fluid_type );
4074 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 3 ) ) {
4075 // We want the actual debris, but not the rubble marker or dirt.
4076 make_rubble( { i, j, abs_sub.z } );
4077 ter_set( point( i, j ), fluid_type );
4078 furn_set( point( i, j ), f_null );
4079 }
4080 }
4081 }
4082 break;
4083 }
4084 // minor flooding/sewage
4085 case 2: {
4086 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4087 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4088 // don't flood if stairs because the floor below will not be flooded.
4089 // don't flood if ice lab because there's no mechanic for freezing
4090 // liquid floors.
4091 break;
4092 }
4093 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4094 for( int i = 0; i < 2; ++i ) {
4095 draw_rough_circle( [this, fluid_type]( point p ) {
4096 if( t_thconc_floor == ter( p ) || t_strconc_floor == ter( p ) ||
4097 t_thconc_floor_olight == ter( p ) ) {
4098 ter_set( p, fluid_type );
4099 } else if( has_flag_ter( "DOOR", p ) ) {
4100 // We want the actual debris, but not the rubble marker or dirt.
4101 make_rubble( { p, abs_sub.z } );
4102 ter_set( p, fluid_type );
4103 furn_set( p, f_null );
4104 }
4105 }, point( rng( 1, SEEX * 2 - 2 ), rng( 1, SEEY * 2 - 2 ) ), rng( 3, 6 ) );
4106 }
4107 break;
4108 }
4109 // toxic gas leaks and smoke-filled rooms.
4110 case 3:
4111 case 4: {
4112 bool is_toxic = one_in( 3 );
4113 for( int i = 0; i < SEEX * 2; i++ ) {
4114 for( int j = 0; j < SEEY * 2; j++ ) {
4115 if( one_in( 200 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4116 t_strconc_floor == ter( point( i, j ) ) ) ) {
4117 if( is_toxic ) {
4118 add_field( {i, j, abs_sub.z}, fd_gas_vent, 1 );
4119 } else {
4120 add_field( {i, j, abs_sub.z}, fd_smoke_vent, 2 );
4121 }
4122 }
4123 }
4124 }
4125 break;
4126 }
4127 // portal with an artifact effect.
4128 case 5: {
4129 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4130 std::vector<artifact_natural_property> valid_props = {
4137 };
4138 draw_rough_circle( [this]( point p ) {
4139 if( has_flag_ter( "GOES_DOWN", p ) ||
4140 has_flag_ter( "GOES_UP", p ) ||
4141 has_flag_ter( "CONSOLE", p ) ) {
4142 return; // spare stairs and consoles.
4143 }
4144 make_rubble( {p, abs_sub.z } );
4145 ter_set( p, t_thconc_floor );
4146 }, center.xy(), 4 );
4147 furn_set( center.xy(), f_null );
4149 create_anomaly( center, random_entry( valid_props ), false );
4150 break;
4151 }
4152 // radioactive accident.
4153 case 6: {
4154 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4155 if( has_flag_ter( "WALL", center.xy() ) ) {
4156 // just skip it, we don't want to risk embedding radiation out of sight.
4157 break;
4158 }
4159 draw_rough_circle( [this]( point p ) {
4160 set_radiation( p, 10 );
4161 }, center.xy(), rng( 7, 12 ) );
4162 draw_circle( [this]( point p ) {
4163 set_radiation( p, 20 );
4164 }, center.xy(), rng( 5, 8 ) );
4165 draw_circle( [this]( point p ) {
4166 set_radiation( p, 30 );
4167 }, center.xy(), rng( 2, 4 ) );
4168 draw_circle( [this]( point p ) {
4169 set_radiation( p, 50 );
4170 }, center.xy(), 1 );
4171 draw_circle( [this]( point p ) {
4172 if( has_flag_ter( "GOES_DOWN", p ) ||
4173 has_flag_ter( "GOES_UP", p ) ||
4174 has_flag_ter( "CONSOLE", p ) ) {
4175 return; // spare stairs and consoles.
4176 }
4177 make_rubble( {p, abs_sub.z } );
4178 ter_set( p, t_thconc_floor );
4179 }, center.xy(), 1 );
4180
4182 center.xy() + point_west, 1, true );
4184 center.xy() + point_west, 1, true );
4185
4186 // damaged mininuke/plut thrown past edge of rubble so the player can see it.
4187 int marker_x = center.x - 2 + 4 * rng( 0, 1 );
4188 int marker_y = center.y + rng( -2, 2 );
4189 if( one_in( 4 ) ) {
4190 spawn_item(
4191 point( marker_x, marker_y ), "mininuke", 1, 1, calendar::start_of_cataclysm, rng( 2, 4 )
4192 );
4193 } else {
4194 item newliquid( "plut_slurry_dense", calendar::start_of_cataclysm );
4195 newliquid.charges = 1;
4196 add_item_or_charges( tripoint( marker_x, marker_y, get_abs_sub().z ),
4197 newliquid );
4198 }
4199 break;
4200 }
4201 // portal with fungal invasion
4202 case 7: {
4203 for( int i = 0; i < EAST_EDGE; i++ ) {
4204 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4205 // Create a mostly spread fungal area throughout entire lab.
4206 if( !one_in( 5 ) && ( has_flag( "FLAT", point( i, j ) ) ) ) {
4207 ter_set( point( i, j ), t_fungus_floor_in );
4208 if( has_flag_furn( "ORGANIC", point( i, j ) ) ) {
4209 furn_set( point( i, j ), f_fungal_clump );
4210 }
4211 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 5 ) ) {
4212 ter_set( point( i, j ), t_fungus_floor_in );
4213 } else if( has_flag_ter( "WALL", point( i, j ) ) && one_in( 3 ) ) {
4214 ter_set( point( i, j ), t_fungus_wall );
4215 }
4216 }
4217 }
4218 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4219
4220 // Make a portal surrounded by more dense fungal stuff and a fungaloid.
4221 draw_rough_circle( [this]( point p ) {
4222 if( has_flag_ter( "GOES_DOWN", p ) ||
4223 has_flag_ter( "GOES_UP", p ) ||
4224 has_flag_ter( "CONSOLE", p ) ) {
4225 return; // spare stairs and consoles.
4226 }
4227 if( has_flag_ter( "WALL", p ) ) {
4228 ter_set( p, t_fungus_wall );
4229 } else {
4231 if( one_in( 3 ) ) {
4233 } else if( one_in( 10 ) ) {
4234 ter_set( p, t_marloss );
4235 }
4236 }
4237 }, center.xy(), 3 );
4239 furn_set( center.xy(), f_null );
4241 place_spawns( GROUP_FUNGI_FUNGALOID, 1, center.xy() + point( -2, -2 ),
4242 center.xy() + point( 2, 2 ), 1, true );
4243
4244 break;
4245 }
4246 }
4247 }
4248 } else if( terrain_type == "lab_finale" || terrain_type == "ice_lab_finale" ||
4249 terrain_type == "central_lab_finale" || terrain_type == "tower_lab_finale" ) {
4250
4251 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
4252 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
4253 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
4254
4255 if( ice_lab ) {
4256 int temperature = -20 + 30 * dat.zlevel();
4258 set_temperature( p2 + point( SEEX, 0 ), temperature );
4259 set_temperature( p2 + point( 0, SEEY ), temperature );
4261 }
4262
4263 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
4264 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
4265 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
4266 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
4267
4268 // If you remove the usage of "lab_finale_1level" here, remove it from mapgen_factory::get_usages above as well.
4269 if( oter_mapgen.generate( dat, "lab_finale_1level" ) ) {
4270 // If the map template hasn't handled borders, handle them in code.
4271 // Rotated maps cannot handle borders and have to be caught in code.
4272 // We determine if a border isn't handled by checking the east-facing
4273 // border space where the door normally is -- it should be a wall or door.
4274 tripoint east_border( 23, 11, abs_sub.z );
4275 if( !has_flag_ter( "WALL", east_border ) && !has_flag_ter( "DOOR", east_border ) ) {
4276 // TODO: create a ter_reset function that does ter_set, furn_set, and i_clear?
4277 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4278 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4279 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass : t_concrete_wall;
4280 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass : t_concrete_wall;
4281 for( int i = 0; i < SEEX * 2; i++ ) {
4282 ter_set( point( 23, i ), rw_type );
4283 furn_set( point( 23, i ), f_null );
4284 i_clear( tripoint( 23, i, get_abs_sub().z ) );
4285
4286 ter_set( point( i, 23 ), bw_type );
4287 furn_set( point( i, 23 ), f_null );
4288 i_clear( tripoint( i, 23, get_abs_sub().z ) );
4289
4290 if( lw == 2 ) {
4291 ter_set( point( 0, i ), lw_type );
4292 furn_set( point( 0, i ), f_null );
4293 i_clear( tripoint( 0, i, get_abs_sub().z ) );
4294 }
4295 if( tw == 2 ) {
4296 ter_set( point( i, 0 ), tw_type );
4297 furn_set( point( i, 0 ), f_null );
4298 i_clear( tripoint( i, 0, get_abs_sub().z ) );
4299 }
4300 }
4301 if( rw != 2 ) {
4302 ter_set( point( 23, 11 ), t_door_metal_c );
4303 ter_set( point( 23, 12 ), t_door_metal_c );
4304 }
4305 if( bw != 2 ) {
4306 ter_set( point( 11, 23 ), t_door_metal_c );
4307 ter_set( point( 12, 23 ), t_door_metal_c );
4308 }
4309 }
4310 }
4311
4312 // Handle stairs in the unlikely case they are needed.
4313 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
4314 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
4315 const auto predicate = [this]( const tripoint & p ) {
4316 return ter( p ) == t_thconc_floor && furn( p ) == f_null &&
4317 tr_at( p ).is_null();
4318 };
4319 const auto range = points_in_rectangle( { 0, 0, abs_sub.z },
4320 { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
4321 if( const auto p = random_point( range, predicate ) ) {
4322 ter_set( *p, t_stair_type );
4323 }
4324 }
4325 };
4326 maybe_insert_stairs( dat.above(), t_stairs_up );
4327 maybe_insert_stairs( terrain_type, t_stairs_down );
4328
4329 int light_odds = 0;
4330 // central labs are always fully lit, other labs have half chance of some lights.
4331 if( central_lab ) {
4332 light_odds = 1;
4333 } else if( one_in( 2 ) ) {
4334 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4335 }
4336 if( light_odds > 0 ) {
4337 for( int i = 0; i < SEEX * 2; i++ ) {
4338 for( int j = 0; j < SEEY * 2; j++ ) {
4339 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4340 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4342 }
4343 }
4344 }
4345 }
4346 }
4347 }
4348}
void set_temperature(const tripoint &p, int temperature)
Definition: map.cpp:4200
void i_clear(const tripoint &p)
Definition: map.cpp:4248
void trap_set(const tripoint &p, const trap_id &type)
Definition: map.cpp:5310
bool generate(mapgendata &dat, const std::string &key, const int hardcoded_weight=0) const
Definition: mapgen.cpp:355
int zlevel() const
Definition: mapgendata.h:99
void draw_rough_circle(std::function< void(point)>set, point p, int rad)
field_type_id fd_gas_vent
Definition: field_type.cpp:350
field_type_id fd_smoke_vent
Definition: field_type.cpp:385
ter_id t_door_glass_frosted_c
Definition: mapdata.cpp:667
ter_id t_slime
Definition: mapdata.cpp:640
ter_id t_strconc_floor
Definition: mapdata.cpp:634
furn_id f_fungal_clump
Definition: mapdata.cpp:1119
ter_id t_fungus_floor_in
Definition: mapdata.cpp:693
ter_id t_fungus_wall
Definition: mapdata.cpp:693
ter_id t_reinforced_glass
Definition: mapdata.cpp:653
ter_id t_concrete_wall
Definition: mapdata.cpp:649
ter_id t_floor
Definition: mapdata.cpp:635
ter_id t_thconc_floor_olight
Definition: mapdata.cpp:634
ter_id t_bars
Definition: mapdata.cpp:656
ter_id t_thconc_floor
Definition: mapdata.cpp:634
furn_id f_rubble_rock
Definition: mapdata.cpp:1100
ter_id t_stairs_up
Definition: mapdata.cpp:721
ter_id t_stairs_down
Definition: mapdata.cpp:721
ter_id t_marloss
Definition: mapdata.cpp:693
ter_id t_door_metal_locked
Definition: mapdata.cpp:665
ter_id t_card_science
Definition: mapdata.cpp:725
furn_id f_flower_fungal
Definition: mapdata.cpp:1119
static const mongroup_id GROUP_HAZMATBOT("GROUP_HAZMATBOT")
static const mongroup_id GROUP_TURRET("GROUP_TURRET")
const int SOUTH_EDGE
Definition: mapgen.cpp:2962
static void science_room(map *m, point p1, point p2, int z, int rotate)
Definition: mapgen.cpp:5787
const int EAST_EDGE
Definition: mapgen.cpp:2963
static mapgen_factory oter_mapgen
Definition: mapgen.cpp:364
static const mongroup_id GROUP_FUNGI_FUNGALOID("GROUP_FUNGI_FUNGALOID")
static const mongroup_id GROUP_LAB("GROUP_LAB")
static const trap_str_id tr_portal("tr_portal")
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References mapgendata::above(), abs_sub, add_field(), add_item_or_charges(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_GLOWING, ARTPROP_SCALED, ARTPROP_WARM, ARTPROP_WHISPERING, center, item::charges, connects_to(), contains, create_anomaly(), debugmsg, destroy(), draw_circle(), draw_rough_circle(), mapgendata::east(), EAST_EDGE, f_flower_fungal, f_fungal_clump, f_null, f_rubble_rock, fd_gas_vent, fd_smoke_vent, furn(), furn_set(), mapgen_factory::generate(), get_abs_sub(), GROUP_FUNGI_FUNGALOID, GROUP_HAZMATBOT, GROUP_LAB, GROUP_TURRET, has_flag(), has_flag_furn(), has_flag_ter(), i_clear(), trap::is_null(), is_ot_match(), make_rubble(), mapgendata::north(), one_in(), oter_mapgen, place_spawns(), point_west, point_zero, points_in_rectangle(), prefix, random_entry(), random_point(), range, rng(), rotate(), science_room(), SEEX, SEEY, set_radiation(), set_temperature(), mapgendata::south(), SOUTH_EDGE, spawn_item(), calendar::start_of_cataclysm, t_bars, t_card_science, t_concrete_wall, t_dirt, t_door_glass_frosted_c, t_door_metal_c, t_door_metal_locked, t_floor, t_fungus_floor_in, t_fungus_wall, t_marloss, t_reinforced_glass, t_rock_floor, t_sewage, t_slime, t_stairs_down, t_stairs_up, t_strconc_floor, t_thconc_floor, t_thconc_floor_olight, t_water_sh, ter(), ter_set(), terrain, mapgendata::terrain_type(), tr_at(), tr_portal, trap_set(), type, mapgendata::west(), tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_line_furn()

void map::draw_line_furn ( const furn_id type,
point  p1,
point  p2 
)

Definition at line 8504 of file map.cpp.

8505{
8506 draw_line( [this, type]( point p ) {
8507 this->furn_set( p, type );
8508 }, p1, p2 );
8509}
void draw_line(std::function< void(point)>set, point p1, point p2)

References draw_line(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), and line_furn().

◆ draw_line_ter()

void map::draw_line_ter ( const ter_id type,
point  p1,
point  p2 
)

Definition at line 8497 of file map.cpp.

8498{
8499 draw_line( [this, type]( point p ) {
8500 this->ter_set( p, type );
8501 }, p1, p2 );
8502}

References draw_line(), ter_set(), and type.

Referenced by jmapgen_setmap::apply(), and line().

◆ draw_map()

void map::draw_map ( mapgendata dat)
protected

Definition at line 2922 of file mapgen.cpp.

2923{
2924 const oter_id &terrain_type = dat.terrain_type();
2925 const std::string function_key = terrain_type->get_mapgen_id();
2926 bool found = true;
2927
2928 const bool generated = run_mapgen_func( function_key, dat );
2929
2930 if( !generated ) {
2931 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ||
2932 is_ot_match( "slime_pit", terrain_type, ot_match_type::prefix ) ) {
2933 draw_slimepit( dat );
2934 } else if( is_ot_match( "triffid", terrain_type, ot_match_type::prefix ) ) {
2935 draw_triffid( dat );
2936 } else if( is_ot_match( "office", terrain_type, ot_match_type::prefix ) ) {
2937 draw_office_tower( dat );
2938 } else if( is_ot_match( "temple", terrain_type, ot_match_type::prefix ) ) {
2939 draw_temple( dat );
2940 } else if( is_ot_match( "mine", terrain_type, ot_match_type::prefix ) ) {
2941 draw_mine( dat );
2942 } else if( is_ot_match( "anthill", terrain_type, ot_match_type::contains ) ) {
2943 draw_anthill( dat );
2944 } else if( is_ot_match( "lab", terrain_type, ot_match_type::contains ) ) {
2945 draw_lab( dat );
2946 } else {
2947 found = false;
2948 }
2949 }
2950
2951 if( !found ) {
2952 // not one of the hardcoded ones!
2953 // load from JSON???
2954 debugmsg( "Error: tried to generate map for omtype %s, \"%s\" (id_mapgen %s)",
2955 terrain_type.id().c_str(), terrain_type->get_name(), function_key.c_str() );
2956 fill_background( this, t_floor );
2957 }
2958
2959 draw_connections( dat );
2960}
void draw_office_tower(mapgendata &dat)
Definition: mapgen.cpp:2965
void draw_mine(mapgendata &dat)
Definition: mapgen.cpp:4596
void draw_triffid(mapgendata &dat)
Definition: mapgen.cpp:4926
void draw_anthill(mapgendata &dat)
Definition: mapgen.cpp:4864
void draw_slimepit(mapgendata &dat)
Definition: mapgen.cpp:4882
void draw_lab(mapgendata &dat)
Definition: mapgen.cpp:3553
void draw_connections(mapgendata &dat)
Definition: mapgen.cpp:5074
void draw_temple(mapgendata &dat)
Definition: mapgen.cpp:4350
void fill_background(map *m, const ter_id &type)
Definition: mapgen.cpp:6298
bool run_mapgen_func(const std::string &mapgen_id, mapgendata &dat)
Definition: mapgen.cpp:6522
std::string get_name() const
Definition: omdata.h:205
std::string get_mapgen_id() const
Definition: overmap.cpp:798

References string_id< T >::c_str(), contains, debugmsg, draw_anthill(), draw_connections(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), fill_background(), oter_t::get_mapgen_id(), oter_t::get_name(), int_id< T >::id(), is_ot_match(), prefix, run_mapgen_func(), t_floor, and mapgendata::terrain_type().

Referenced by generate().

◆ draw_maptile()

bool map::draw_maptile ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Internal version of the drawsq.

Keeps a cached maptile for less re-getting. Returns false if it has drawn all it should, true if draw_from_above should be called after.

Definition at line 6005 of file map.cpp.

6007{
6008 drawsq_params param = params;
6009 nc_color tercol;
6010 const ter_t &curr_ter = curr_maptile.get_ter_t();
6011 const furn_t &curr_furn = curr_maptile.get_furn_t();
6012 const trap &curr_trap = curr_maptile.get_trap().obj();
6013 const field &curr_field = curr_maptile.get_field();
6014 int sym;
6015 bool hi = false;
6016 bool graf = false;
6017 bool draw_item_sym = false;
6018
6019 int terrain_sym;
6020 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
6021 terrain_sym = determine_wall_corner( p );
6022 } else {
6023 terrain_sym = curr_ter.symbol();
6024 }
6025
6026 if( curr_furn.id ) {
6027 sym = curr_furn.symbol();
6028 tercol = curr_furn.color();
6029 } else {
6030 sym = terrain_sym;
6031 tercol = curr_ter.color();
6032 }
6033 if( curr_ter.has_flag( TFLAG_SWIMMABLE ) && curr_ter.has_flag( TFLAG_DEEP_WATER ) &&
6034 !g->u.is_underwater() ) {
6035 param.show_items( false ); // Can only see underwater items if WE are underwater
6036 }
6037 // If there's a trap here, and we have sufficient perception, draw that instead
6038 if( curr_trap.can_see( p, g->u ) ) {
6039 tercol = curr_trap.color;
6040 if( curr_trap.sym == '%' ) {
6041 switch( rng( 1, 5 ) ) {
6042 case 1:
6043 sym = '*';
6044 break;
6045 case 2:
6046 sym = '0';
6047 break;
6048 case 3:
6049 sym = '8';
6050 break;
6051 case 4:
6052 sym = '&';
6053 break;
6054 case 5:
6055 sym = '+';
6056 break;
6057 }
6058 } else {
6059 sym = curr_trap.sym;
6060 }
6061 }
6062 if( curr_field.field_count() > 0 ) {
6063 const field_type_id &fid = curr_field.displayed_field_type();
6064 const field_entry *fe = curr_field.find_field( fid );
6065 const auto field_symbol = fid->get_symbol();
6066 if( field_symbol == "&" || fe == nullptr ) {
6067 // Do nothing, a '&' indicates invisible fields.
6068 } else if( field_symbol == "*" ) {
6069 // A random symbol.
6070 switch( rng( 1, 5 ) ) {
6071 case 1:
6072 sym = '*';
6073 break;
6074 case 2:
6075 sym = '0';
6076 break;
6077 case 3:
6078 sym = '8';
6079 break;
6080 case 4:
6081 sym = '&';
6082 break;
6083 case 5:
6084 sym = '+';
6085 break;
6086 }
6087 } else {
6088 // A field symbol '%' indicates the field should not hide
6089 // items/terrain. When the symbol is not '%' it will
6090 // hide items (the color is still inverted if there are items,
6091 // but the tile symbol is not changed).
6092 // draw_item_sym indicates that the item symbol should be used
6093 // even if sym is not '.'.
6094 // As we don't know at this stage if there are any items
6095 // (that are visible to the player!), we always set the symbol.
6096 // If there are items and the field does not hide them,
6097 // the code handling items will override it.
6098 draw_item_sym = ( field_symbol == "'%" );
6099 // If field display_priority is > 1, and the field is set to hide items,
6100 //draw the field as it obscures what's under it.
6101 if( ( field_symbol != "%" && fid.obj().priority > 1 ) || ( field_symbol != "%" &&
6102 sym == '.' ) ) {
6103 // default terrain '.' and
6104 // non-default field symbol -> field symbol overrides terrain
6105 sym = field_symbol[0];
6106 }
6107 tercol = fe->color();
6108 }
6109 }
6110
6111 // TODO: change the local variable sym to std::string and use it instead of this hack.
6112 // Currently this are different variables because terrain/... uses int as symbol type and
6113 // item now use string. Ideally they should all be strings.
6114 std::string item_sym;
6115
6116 // If there are items here, draw those instead
6117 if( param.show_items() && curr_maptile.get_item_count() > 0 && sees_some_items( p, g->u ) ) {
6118 // if there's furniture/terrain/trap/fields (sym!='.')
6119 // and we should not override it, then only highlight the square
6120 if( sym != '.' && sym != '%' && !draw_item_sym ) {
6121 hi = true;
6122 } else {
6123 // otherwise override with the symbol of the last item
6124 item_sym = curr_maptile.get_uppermost_item().symbol();
6125 if( !draw_item_sym ) {
6126 tercol = curr_maptile.get_uppermost_item().color();
6127 }
6128 if( curr_maptile.get_item_count() > 1 ) {
6129 param.highlight( !param.highlight() );
6130 }
6131 }
6132 }
6133
6134 int memory_sym = sym;
6135 int veh_part = 0;
6136 const vehicle *veh = veh_at_internal( p, veh_part );
6137 if( veh != nullptr ) {
6138 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( veh_part ) ) );
6139 tercol = veh->part_color( veh_part );
6140 item_sym.clear(); // clear the item symbol so `sym` is used instead.
6141
6142 if( !veh->forward_velocity() && !veh->player_in_control( g->u ) ) {
6143 memory_sym = sym;
6144 }
6145 }
6146
6147 if( param.memorize() && check_and_set_seen_cache( p ) ) {
6148 g->u.memorize_symbol( getabs( p ), memory_sym );
6149 }
6150
6151 // If there's graffiti here, change background color
6152 if( curr_maptile.has_graffiti() ) {
6153 graf = true;
6154 }
6155
6156 const auto u_vision = g->u.get_vision_modes();
6157 if( u_vision[BOOMERED] ) {
6158 tercol = c_magenta;
6159 } else if( u_vision[NV_GOGGLES] ) {
6160 tercol = param.bright_light() ? c_white : c_light_green;
6161 } else if( param.low_light() ) {
6162 tercol = c_dark_gray;
6163 } else if( u_vision[DARKNESS] ) {
6164 tercol = c_dark_gray;
6165 }
6166
6167 if( param.highlight() ) {
6168 tercol = invert_color( tercol );
6169 } else if( hi ) {
6170 tercol = hilite( tercol );
6171 } else if( graf ) {
6172 tercol = red_background( tercol );
6173 }
6174
6175 if( item_sym.empty() && sym == ' ' ) {
6176 if( !zlevels || p.z <= -OVERMAP_DEPTH || !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6177 // Print filler symbol
6178 sym = ' ';
6179 tercol = c_black;
6180 } else {
6181 // Draw tile underneath this one instead
6182 return false;
6183 }
6184 }
6185
6186 if( params.output() ) {
6187 if( item_sym.empty() ) {
6188 wputch( w, tercol, sym );
6189 } else {
6190 wprintz( w, tercol, item_sym );
6191 }
6192 }
6193 return true;
6194}
nc_color color() const
Definition: field.cpp:94
field_entry * find_field(const field_type_id &field_type_to_find)
Returns a field entry corresponding to the field_type_id parameter passed in.
Definition: field.cpp:153
field_type_id displayed_field_type() const
Returns field type that should be drawn.
Definition: field.cpp:275
unsigned int field_count() const
Definition: field.cpp:246
bool check_and_set_seen_cache(const tripoint &p) const
Definition: map.cpp:8959
bool sees_some_items(const tripoint &p, const Creature &who) const
Check if creature can see some items at p.
Definition: map.cpp:4856
nc_color part_color(int p, bool exact=false) const
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:279
float forward_velocity() const
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color hilite(const nc_color &c)
Definition: color.cpp:509
@ TFLAG_SWIMMABLE
Definition: mapdata.h:280
void wprintz(const catacurses::window &w, const nc_color &FG, const std::string &text)
Definition: output.cpp:2089
constexpr drawsq_params & show_items(bool v)
Whether to draw items on the tile.
Definition: map.h:212
int priority
Definition: field_type.h:177
std::string get_symbol(int level=0) const
Definition: field_type.h:198
furn_str_id id
Definition: mapdata.h:504
nc_color color
Definition: trap.h:93
int sym
Definition: trap.h:92

References BOOMERED, drawsq_params::bright_light(), c_black, c_dark_gray, c_light_green, c_magenta, c_white, trap::can_see(), check_and_set_seen_cache(), field_entry::color(), item::color(), map_data_common_t::color(), trap::color, DARKNESS, determine_wall_corner(), tileray::dir_symbol(), field::displayed_field_type(), vehicle::face, field::field_count(), field::find_field(), vehicle::forward_velocity(), g, maptile::get_field(), maptile::get_furn_t(), maptile::get_item_count(), field_type::get_symbol(), maptile::get_ter_t(), maptile::get_trap(), maptile::get_uppermost_item(), getabs(), map_data_common_t::has_flag(), maptile::has_graffiti(), drawsq_params::highlight(), hilite(), furn_t::id, invert_color(), drawsq_params::low_light(), drawsq_params::memorize(), NV_GOGGLES, int_id< T >::obj(), drawsq_params::output(), OVERMAP_DEPTH, vehicle::part_color(), vehicle::part_sym(), vehicle::player_in_control(), field_type::priority, red_background(), rng(), sees_some_items(), drawsq_params::show_items(), special_symbol(), trap::sym, item::symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, TFLAG_SWIMMABLE, veh_at_internal(), wprintz(), wputch(), tripoint::z, and zlevels.

Referenced by draw(), and drawsq().

◆ draw_mine()

void map::draw_mine ( mapgendata dat)
protected

Definition at line 4596 of file mapgen.cpp.

4597{
4598 const oter_id &terrain_type = dat.terrain_type();
4599 if( terrain_type == "mine" || terrain_type == "mine_down" ) {
4600 if( is_ot_match( "mine", dat.north(), ot_match_type::prefix ) ) {
4601 dat.n_fac = ( one_in( 10 ) ? 0 : -2 );
4602 } else {
4603 dat.n_fac = 4;
4604 }
4605 if( is_ot_match( "mine", dat.east(), ot_match_type::prefix ) ) {
4606 dat.e_fac = ( one_in( 10 ) ? 0 : -2 );
4607 } else {
4608 dat.e_fac = 4;
4609 }
4610 if( is_ot_match( "mine", dat.south(), ot_match_type::prefix ) ) {
4611 dat.s_fac = ( one_in( 10 ) ? 0 : -2 );
4612 } else {
4613 dat.s_fac = 4;
4614 }
4615 if( is_ot_match( "mine", dat.west(), ot_match_type::prefix ) ) {
4616 dat.w_fac = ( one_in( 10 ) ? 0 : -2 );
4617 } else {
4618 dat.w_fac = 4;
4619 }
4620
4621 for( int i = 0; i < SEEX * 2; i++ ) {
4622 for( int j = 0; j < SEEY * 2; j++ ) {
4623 if( i >= dat.w_fac + rng( 0, 2 ) && i <= EAST_EDGE - dat.e_fac - rng( 0, 2 ) &&
4624 j >= dat.n_fac + rng( 0, 2 ) && j <= SOUTH_EDGE - dat.s_fac - rng( 0, 2 ) &&
4625 i + j >= 4 && ( SEEX * 2 - i ) + ( SEEY * 2 - j ) >= 6 ) {
4626 ter_set( point( i, j ), t_rock_floor );
4627 } else {
4628 ter_set( point( i, j ), t_rock );
4629 }
4630 }
4631 }
4632
4633 // Not an entrance; maybe some hazards!
4634 switch( rng( 0, 4 ) ) {
4635 case 0:
4636 break; // Nothing! Lucky!
4637
4638 case 1: {
4639 // Toxic gas
4640 point gas_vent_location( rng( 9, 14 ), rng( 9, 14 ) );
4641 ter_set( point( gas_vent_location ), t_rock );
4642 add_field( { gas_vent_location, abs_sub.z }, fd_gas_vent, 2 );
4643 }
4644 break;
4645
4646 case 2: {
4647 // Lava
4648 point start_location( rng( 6, SEEX ), rng( 6, SEEY ) );
4649 point end_location( rng( SEEX + 1, SEEX * 2 - 7 ), rng( SEEY + 1, SEEY * 2 - 7 ) );
4650 const int num = rng( 2, 4 );
4651 for( int i = 0; i < num; i++ ) {
4652 int lx1 = start_location.x + rng( -1, 1 );
4653 int lx2 = end_location.x + rng( -1, 1 );
4654 int ly1 = start_location.y + rng( -1, 1 );
4655 int ly2 = end_location.y + rng( -1, 1 );
4656 line( this, t_lava, point( lx1, ly1 ), point( lx2, ly2 ) );
4657 }
4659 tripoint( end_location,
4660 abs_sub.z ) ) ) {
4661 if( ter( ore ) == t_rock_floor && one_in( 10 ) ) {
4662 spawn_item( ore, "chunk_sulfur" );
4663 }
4664 }
4665 }
4666 break;
4667
4668 case 3: {
4669 // Wrecked equipment
4670 point wreck_location( rng( 9, 14 ), rng( 9, 14 ) );
4671 for( int i = wreck_location.x - 3; i < wreck_location.x + 3; i++ ) {
4672 for( int j = wreck_location.y - 3; j < wreck_location.y + 3; j++ ) {
4673 if( !one_in( 4 ) ) {
4675 }
4676 }
4677 }
4678 }
4679 break;
4680
4681 case 4: {
4682 // Dead miners
4683 const int num_bodies = rng( 4, 8 );
4684 for( int i = 0; i < num_bodies; i++ ) {
4685 if( const auto body = random_point( *this, [this]( const tripoint & p ) {
4686 return move_cost( p ) == 2;
4687 } ) ) {
4688 add_item( *body, item::make_corpse() );
4689 place_items( item_group_id( "mon_zombie_miner_death_drops" ), 100, *body, *body,
4691 }
4692 }
4693 }
4694 break;
4695
4696 }
4697
4698 if( terrain_type == "mine_down" ) { // Don't forget to build a slope down!
4699 std::vector<direction> open;
4700 if( dat.n_fac == 4 ) {
4701 open.push_back( direction::NORTH );
4702 }
4703 if( dat.e_fac == 4 ) {
4704 open.push_back( direction::EAST );
4705 }
4706 if( dat.s_fac == 4 ) {
4707 open.push_back( direction::SOUTH );
4708 }
4709 if( dat.w_fac == 4 ) {
4710 open.push_back( direction::WEST );
4711 }
4712
4713 if( open.empty() ) { // We'll have to build it in the center
4714 int tries = 0;
4715 point p;
4716 bool okay = true;
4717 do {
4718 p.x = rng( SEEX - 6, SEEX + 1 );
4719 p.y = rng( SEEY - 6, SEEY + 1 );
4720 okay = true;
4721 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4722 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4723 if( ter( point( i, j ) ) != t_rock_floor ) {
4724 okay = false;
4725 }
4726 }
4727 }
4728 if( !okay ) {
4729 tries++;
4730 }
4731 } while( !okay && tries < 10 );
4732 if( tries == 10 ) { // Clear the area around the slope down
4733 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4734 }
4735 // NOLINTNEXTLINE(cata-use-named-point-constants)
4736 square( this, t_slope_down, p + point( 1, 1 ), p + point( 2, 2 ) );
4737 } else { // We can build against a wall
4738 switch( random_entry( open ) ) {
4739 case direction::NORTH:
4740 square( this, t_rock_floor, point( SEEX - 3, 6 ), point( SEEX + 2, SEEY ) );
4741 line( this, t_slope_down, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4742 break;
4743 case direction::EAST:
4744 square( this, t_rock_floor, point( SEEX + 1, SEEY - 3 ), point( SEEX * 2 - 7, SEEY + 2 ) );
4745 line( this, t_slope_down, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4746 break;
4747 case direction::SOUTH:
4748 square( this, t_rock_floor, point( SEEX - 3, SEEY + 1 ), point( SEEX + 2, SEEY * 2 - 7 ) );
4749 line( this, t_slope_down, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4750 break;
4751 case direction::WEST:
4752 square( this, t_rock_floor, point( 6, SEEY - 3 ), point( SEEX, SEEY + 2 ) );
4753 line( this, t_slope_down, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4754 break;
4755 default:
4756 break;
4757 }
4758 }
4759 } // Done building a slope down
4760
4761 if( dat.above() == "mine_down" ) { // Don't forget to build a slope up!
4762 std::vector<direction> open;
4763 if( dat.n_fac == 6 && ter( point( SEEX, 6 ) ) != t_slope_down ) {
4764 open.push_back( direction::NORTH );
4765 }
4766 if( dat.e_fac == 6 && ter( point( SEEX * 2 - 7, SEEY ) ) != t_slope_down ) {
4767 open.push_back( direction::EAST );
4768 }
4769 if( dat.s_fac == 6 && ter( point( SEEX, SEEY * 2 - 7 ) ) != t_slope_down ) {
4770 open.push_back( direction::SOUTH );
4771 }
4772 if( dat.w_fac == 6 && ter( point( 6, SEEY ) ) != t_slope_down ) {
4773 open.push_back( direction::WEST );
4774 }
4775
4776 if( open.empty() ) { // We'll have to build it in the center
4777 int tries = 0;
4778 point p;
4779 bool okay = true;
4780 do {
4781 p.x = rng( SEEX - 6, SEEX + 1 );
4782 p.y = rng( SEEY - 6, SEEY + 1 );
4783 okay = true;
4784 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4785 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4786 if( ter( point( i, j ) ) != t_rock_floor ) {
4787 okay = false;
4788 }
4789 }
4790 }
4791 if( !okay ) {
4792 tries++;
4793 }
4794 } while( !okay && tries < 10 );
4795 if( tries == 10 ) { // Clear the area around the slope down
4796 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4797 }
4798 // NOLINTNEXTLINE(cata-use-named-point-constants)
4799 square( this, t_slope_up, p + point( 1, 1 ), p + point( 2, 2 ) );
4800
4801 } else { // We can build against a wall
4802 switch( random_entry( open ) ) {
4803 case direction::NORTH:
4804 line( this, t_slope_up, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4805 break;
4806 case direction::EAST:
4807 line( this, t_slope_up, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4808 break;
4809 case direction::SOUTH:
4810 line( this, t_slope_up, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4811 break;
4812 case direction::WEST:
4813 line( this, t_slope_up, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4814 break;
4815 default:
4816 break;
4817 }
4818 }
4819 } // Done building a slope up
4820 } else if( terrain_type == "mine_finale" ) {
4821 // Set up the basic chamber
4822 for( int i = 0; i < SEEX * 2; i++ ) {
4823 for( int j = 0; j < SEEY * 2; j++ ) {
4824 if( i > rng( 1, 3 ) && i < SEEX * 2 - rng( 2, 4 ) &&
4825 j > rng( 1, 3 ) && j < SEEY * 2 - rng( 2, 4 ) ) {
4826 ter_set( point( i, j ), t_rock_floor );
4827 } else {
4828 ter_set( point( i, j ), t_rock );
4829 }
4830 }
4831 }
4832
4833 // Now draw the entrance(s)
4834 if( dat.north() == "mine" ) {
4835 square( this, t_rock_floor, point( SEEX, 0 ), point( SEEX + 1, 3 ) );
4836 }
4837
4838 if( dat.east() == "mine" ) {
4839 square( this, t_rock_floor, point( SEEX * 2 - 4, SEEY ), point( EAST_EDGE, SEEY + 1 ) );
4840 }
4841
4842 if( dat.south() == "mine" ) {
4843 square( this, t_rock_floor, point( SEEX, SEEY * 2 - 4 ), point( SEEX + 1, SOUTH_EDGE ) );
4844 }
4845
4846 if( dat.west() == "mine" ) {
4847 square( this, t_rock_floor, point( 0, SEEY ), point( 3, SEEY + 1 ) );
4848 }
4849
4850 // Now, pick and generate a type of finale!
4851 // The Thing dog
4852 const int num_bodies = rng( 4, 8 );
4853 for( int i = 0; i < num_bodies; i++ ) {
4854 point p3( rng( 4, SEEX * 2 - 5 ), rng( 4, SEEX * 2 - 5 ) );
4855 add_item( p3, item::make_corpse() );
4856 place_items( item_group_id( "mon_zombie_miner_death_drops" ), 60, p3,
4857 p3, false, calendar::start_of_cataclysm );
4858 }
4859 place_spawns( GROUP_DOG_THING, 1, point( SEEX, SEEX ), point( SEEX + 1, SEEX + 1 ), 1, true, true );
4860 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( SEEY, SEEY + 1 ), abs_sub.z ) );
4861 }
4862}
void spawn_artifact(const tripoint &p)
Definition: map.cpp:4304
std::vector< item * > place_items(const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
Place items from item group in the rectangle f - t.
Definition: mapgen.cpp:5351
static void open()
furn_id f_wreckage
Definition: mapdata.cpp:1100
ter_id t_rock
Definition: mapdata.cpp:676
ter_id t_lava
Definition: mapdata.cpp:698
static const mongroup_id GROUP_DOG_THING("GROUP_DOG_THING")
void square(map *m, const ter_id &type, point p1, point p2)
Definition: mapgen.cpp:6306
void line(map *m, const ter_id &type, point p1, point p2)
Definition: mapgen.cpp:6290

References mapgendata::above(), abs_sub, add_field(), add_item(), mapgendata::e_fac, EAST, mapgendata::east(), EAST_EDGE, f_wreckage, fd_gas_vent, GROUP_DOG_THING, is_ot_match(), line(), item::make_corpse(), make_rubble(), move_cost(), mapgendata::n_fac, NORTH, mapgendata::north(), num, one_in(), open(), place_items(), place_spawns(), points_in_rectangle(), prefix, random_entry(), random_point(), rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH, mapgendata::south(), SOUTH_EDGE, spawn_artifact(), spawn_item(), square(), calendar::start_of_cataclysm, t_lava, t_rock, t_rock_floor, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, WEST, mapgendata::west(), point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ draw_office_tower()

void map::draw_office_tower ( mapgendata dat)
protected

Definition at line 2965 of file mapgen.cpp.

2966{
2967 const oter_id &terrain_type = dat.terrain_type();
2968 const auto place_office_chairs = [&]() {
2969 int num_chairs = rng( 0, 6 );
2970 for( int i = 0; i < num_chairs; i++ ) {
2971 add_vehicle( vproto_id( "swivel_chair" ), point( rng( 6, 16 ), rng( 6, 16 ) ),
2972 0_degrees, -1, -1, false );
2973 }
2974 };
2975
2976 const auto ter_key = mapf::ter_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2977 "t + = D w T S e o h c d l s", t_elevator, t_stairs_down,
2985 const auto fur_key = mapf::furn_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2986 "t + = D w T S e o h c d l s", f_null, f_null, f_null,
2992 f_null );
2993 const auto b_ter_key = mapf::ter_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2994 "t + = D w T S e o h c d l", t_elevator, t_rock,
3002 t_floor, t_floor );
3003 const auto b_fur_key = mapf::furn_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
3004 "t + = D w T S e o h c d l", f_null, f_null, f_null,
3011
3012 if( terrain_type == "office_tower_1_entrance" ) {
3013 dat.fill_groundcover();
3015 "ss%|....+...|...|EEED...\n"
3016 "ss%|----|...|...|EEx|...\n"
3017 "ss%Vcdc^|...|-+-|---|...\n"
3018 "ss%Vch..+...............\n"
3019 "ss%V....|...............\n"
3020 "ss%|----|-|-+--ccc--|...\n"
3021 "ss%|..C..C|.....h..r|-+-\n"
3022 "sss=......+..h.....r|...\n"
3023 "ss%|r..CC.|.ddd....r|T.S\n"
3024 "ss%|------|---------|---\n"
3025 "ss%|####################\n"
3026 "ss%|#|------||------|###\n"
3027 "ss%|#|......||......|###\n"
3028 "ss%|||......||......|###\n"
3029 "ss%||x......||......||##\n"
3030 "ss%|||......||......x|##\n"
3031 "ss%|#|......||......||##\n"
3032 "ss%|#|......||......|###\n"
3033 "ss%|#|XXXXXX||XXXXXX|###\n"
3034 "ss%|-|__,,__||__,,__|---\n"
3035 "ss%% x_,,,,_ __,,__ %%\n"
3036 "ss __,,__ _,,,,_ \n"
3037 "ssssss__,,__ss__,,__ssss\n"
3038 "ssssss______ss______ssss\n", ter_key, fur_key );
3039 place_items( item_group_id( "office" ), 75, point( 4, 2 ), point( 6, 2 ), false,
3041 place_items( item_group_id( "office" ), 75, point( 19, 6 ), point( 19, 6 ), false,
3043 place_items( item_group_id( "office" ), 75, point( 12, 8 ), point( 14, 8 ), false,
3045 if( dat.monster_density() > 1 ) {
3047 } else {
3048 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 1, true );
3049 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 0.15 );
3050 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3051 }
3052 place_office_chairs();
3053
3054 if( dat.north() == "office_tower_1" && dat.west() == "office_tower_1" ) {
3055 rotate( 3 );
3056 } else if( dat.north() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3057 rotate( 0 );
3058 } else if( dat.south() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3059 rotate( 1 );
3060 } else if( dat.west() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3061 rotate( 2 );
3062 }
3063 } else if( terrain_type == "office_tower_1" ) {
3064 // Init to grass & dirt;
3065 dat.fill_groundcover();
3066 if( ( dat.south() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3067 ( dat.north() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ||
3068 ( dat.west() == "office_tower_1" && dat.north() == "office_tower_1_entrance" ) ||
3069 ( dat.south() == "office_tower_1" && dat.west() == "office_tower_1_entrance" ) ) {
3071 " ssssssssssssssssssssssss\n"
3072 "ssssssssssssssssssssssss\n"
3073 "ss \n"
3074 "ss%%%%%%%%%%%%%%%%%%%%%%\n"
3075 "ss%|-HH-|-HH-|-HH-|HH|--\n"
3076 "ss%Vdcxl|dxdl|lddx|..|.S\n"
3077 "ss%Vdh..|dh..|..hd|..+..\n"
3078 "ss%|-..-|-..-|-..-|..|--\n"
3079 "ss%V.................|.T\n"
3080 "ss%V.................|..\n"
3081 "ss%|-..-|-..-|-..-|..|--\n"
3082 "ss%V.h..|..hd|..hd|..|..\n"
3083 "ss%Vdxdl|^dxd|.xdd|..G..\n"
3084 "ss%|----|----|----|..G..\n"
3085 "ss%|llll|..htth......|..\n"
3086 "ss%V.................|..\n"
3087 "ss%V.ddd..........|+-|..\n"
3088 "ss%|..hd|.hh.ceocc|.l|..\n"
3089 "ss%|----|---------|--|..\n"
3090 "ss%Vcdcl|...............\n"
3091 "ss%V.h..+...............\n"
3092 "ss%V...^|...|---|---|...\n"
3093 "ss%|----|...|.R>|EEE|...\n"
3094 "ss%|rrrr|...|.R.|EEED...\n", ter_key, fur_key );
3095 if( dat.monster_density() > 1 ) {
3097 } else {
3098 place_spawns( GROUP_PLAIN, 1, point( 5, 7 ), point( 15, 20 ), 0.1 );
3099 }
3100 place_items( item_group_id( "office" ), 75, point( 4, 23 ), point( 7, 23 ), false,
3102 place_items( item_group_id( "office" ), 75, point( 4, 19 ), point( 7, 19 ), false,
3104 place_items( item_group_id( "office" ), 75, point( 4, 14 ), point( 7, 14 ), false,
3106 place_items( item_group_id( "office" ), 75, point( 5, 16 ), point( 7, 16 ), false,
3108 place_items( item_group_id( "fridge" ), 80, point( 14, 17 ), point( 14, 17 ), false,
3110 place_items( item_group_id( "cleaning" ), 75, point( 19, 17 ), point( 20, 17 ), false,
3112 place_items( item_group_id( "cubical_office" ), 75, point( 6, 12 ), point( 7, 12 ), false,
3114 place_items( item_group_id( "cubical_office" ), 75, point( 12, 11 ), point( 12, 12 ), false,
3116 place_items( item_group_id( "cubical_office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3118 place_items( item_group_id( "cubical_office" ), 75, point( 4, 5 ), point( 5, 5 ), false,
3120 place_items( item_group_id( "cubical_office" ), 75, point( 11, 5 ), point( 12, 5 ), false,
3122 place_items( item_group_id( "cubical_office" ), 75, point( 14, 5 ), point( 16, 5 ), false,
3124 place_office_chairs();
3125
3126 if( dat.west() == "office_tower_1_entrance" ) {
3127 rotate( 1 );
3128 }
3129 if( dat.north() == "office_tower_1_entrance" ) {
3130 rotate( 2 );
3131 }
3132 if( dat.east() == "office_tower_1_entrance" ) {
3133 rotate( 3 );
3134 }
3135 } else if( ( dat.west() == "office_tower_1_entrance" && dat.north() == "office_tower_1" ) ||
3136 ( dat.north() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3137 ( dat.west() == "office_tower_1" && dat.south() == "office_tower_1_entrance" ) ||
3138 ( dat.south() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ) {
3140 "...DEEE|...|..|-----|%ss\n"
3141 "...|EEE|...|..|^...lV%ss\n"
3142 "...|---|-+-|......hdV%ss\n"
3143 "...........G..|..dddV%ss\n"
3144 "...........G..|-----|%ss\n"
3145 ".......|---|..|...ddV%ss\n"
3146 "|+-|...|...+......hdV%ss\n"
3147 "|.l|...|rr.|.^|l...dV%ss\n"
3148 "|--|...|---|--|-----|%ss\n"
3149 "|...........c.......V%ss\n"
3150 "|.......cxh.c.#####.Vsss\n"
3151 "|.......ccccc.......Gsss\n"
3152 "|...................Gsss\n"
3153 "|...................Vsss\n"
3154 "|#..................Gsss\n"
3155 "|#..................Gsss\n"
3156 "|#..................Vsss\n"
3157 "|#............#####.V%ss\n"
3158 "|...................|%ss\n"
3159 "--HHHHHGGHHGGHHHHH--|%ss\n"
3160 "%%%%% ssssssss %%%%%%%ss\n"
3161 " ssssssss ss\n"
3162 "ssssssssssssssssssssssss\n"
3163 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3164 place_items( item_group_id( "office" ), 75, point( 19, 1 ), point( 19, 3 ), false,
3166 place_items( item_group_id( "office" ), 75, point( 17, 3 ), point( 18, 3 ), false,
3168 place_items( item_group_id( "office" ), 90, point( 8, 7 ), point( 9, 7 ), false,
3170 place_items( item_group_id( "cubical_office" ), 75, point( 19, 5 ), point( 19, 7 ), false,
3172 place_items( item_group_id( "cleaning" ), 80, point( 1, 7 ), point( 2, 7 ), false,
3174 if( dat.monster_density() > 1 ) {
3175 place_spawns( GROUP_ZOMBIE, 2, point_zero, point( 14, 10 ), dat.monster_density() );
3176 } else {
3177 place_spawns( GROUP_PLAIN, 1, point( 10, 10 ), point( 14, 10 ), 0.15 );
3178 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3179 }
3180 place_office_chairs();
3181
3182 if( dat.north() == "office_tower_1_entrance" ) {
3183 rotate( 1 );
3184 }
3185 if( dat.east() == "office_tower_1_entrance" ) {
3186 rotate( 2 );
3187 }
3188 if( dat.south() == "office_tower_1_entrance" ) {
3189 rotate( 3 );
3190 }
3191 } else {
3193 "ssssssssssssssssssssssss\n"
3194 "ssssssssssssssssssssssss\n"
3195 " ss\n"
3196 "%%%%%%%%%%%%%%%%%%%%%%ss\n"
3197 "--|---|--HHHH-HHHH--|%ss\n"
3198 ".T|..l|............^|%ss\n"
3199 "..|-+-|...hhhhhhh...V%ss\n"
3200 "--|...G...ttttttt...V%ss\n"
3201 ".S|...G...ttttttt...V%ss\n"
3202 "..+...|...hhhhhhh...V%ss\n"
3203 "--|...|.............|%ss\n"
3204 "..|...|-------------|%ss\n"
3205 "..G....|l.......dxd^|%ss\n"
3206 "..G....G...h....dh..V%ss\n"
3207 "..|....|............V%ss\n"
3208 "..|....|------|llccc|%ss\n"
3209 "..|...........|-----|%ss\n"
3210 "..|...........|...ddV%ss\n"
3211 "..|----|---|......hdV%ss\n"
3212 ".......+...|..|l...dV%ss\n"
3213 ".......|rrr|..|-----|%ss\n"
3214 "...|---|---|..|l.dddV%ss\n"
3215 "...|xEE|.R>|......hdV%ss\n"
3216 "...DEEE|.R.|..|.....V%ss\n", ter_key, fur_key );
3217 spawn_item( point( 18, 15 ), "record_accounting" );
3218 place_items( item_group_id( "cleaning" ), 75, point( 3, 5 ), point( 5, 5 ), false,
3220 place_items( item_group_id( "office" ), 75, point( 10, 7 ), point( 16, 8 ), false,
3222 place_items( item_group_id( "cubical_office" ), 75, point( 15, 15 ), point( 19, 15 ), false,
3224 place_items( item_group_id( "cubical_office" ), 75, point( 16, 12 ), point( 16, 13 ), false,
3226 place_items( item_group_id( "cubical_office" ), 75, point( 17, 19 ), point( 19, 19 ), false,
3228 place_items( item_group_id( "office" ), 75, point( 17, 21 ), point( 19, 21 ), false,
3230 place_items( item_group_id( "office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3232 place_items( item_group_id( "cleaning" ), 75, point( 8, 20 ), point( 10, 20 ), false,
3234 if( dat.monster_density() > 1 ) {
3236 } else {
3237 place_spawns( GROUP_PLAIN, 1, point_zero, point( 9, 15 ), 0.1 );
3238 }
3239 place_office_chairs();
3240
3241 if( dat.west() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3242 rotate( 1 );
3243 } else if( dat.east() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3244 rotate( 2 );
3245 } else if( dat.east() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3246 rotate( 3 );
3247 }
3248 }
3249 } else if( terrain_type == "office_tower_b_entrance" ) {
3250 dat.fill_groundcover();
3252 "sss|........|...|EEED___\n"
3253 "sss|........|...|EEx|___\n"
3254 "sss|........|-+-|---|HHG\n"
3255 "sss|....................\n"
3256 "sss|....................\n"
3257 "sss|....................\n"
3258 "sss|....................\n"
3259 "sss|....,,......,,......\n"
3260 "sss|...,,,,.....,,......\n"
3261 "sss|....,,.....,,,,..xS.\n"
3262 "sss|....,,......,,...SS.\n"
3263 "sss|-|XXXXXX||XXXXXX|---\n"
3264 "sss|s|EEEEEE||EEEEEE|sss\n"
3265 "sss|||EEEEEE||EEEEEE|sss\n"
3266 "sss||xEEEEEE||EEEEEE||ss\n"
3267 "sss|||EEEEEE||EEEEEEx|ss\n"
3268 "sss|s|EEEEEE||EEEEEE||ss\n"
3269 "sss|s|EEEEEE||EEEEEE|sss\n"
3270 "sss|s|------||------|sss\n"
3271 "sss|--------------------\n"
3272 "ssssssssssssssssssssssss\n"
3273 "ssssssssssssssssssssssss\n"
3274 "ssssssssssssssssssssssss\n"
3275 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3276 if( dat.monster_density() > 1 ) {
3278 } else {
3280 }
3281 if( dat.north() == "office_tower_b" && dat.west() == "office_tower_b" ) {
3282 rotate( 3 );
3283 } else if( dat.north() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3284 rotate( 0 );
3285 } else if( dat.south() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3286 rotate( 1 );
3287 } else if( dat.west() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3288 rotate( 2 );
3289 }
3290 } else if( terrain_type == "office_tower_b" ) {
3291 // Init to grass & dirt;
3292 dat.fill_groundcover();
3293 if( ( dat.south() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3294 ( dat.north() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ||
3295 ( dat.west() == "office_tower_b" && dat.north() == "office_tower_b_entrance" ) ||
3296 ( dat.south() == "office_tower_b" && dat.west() == "office_tower_b_entrance" ) ) {
3298 "ssssssssssssssssssssssss\n"
3299 "ssssssssssssssssssssssss\n"
3300 "sss|--------------------\n"
3301 "sss|,.....,.....,.....,S\n"
3302 "sss|,.....,.....,.....,S\n"
3303 "sss|,.....,.....,.....,S\n"
3304 "sss|,.....,.....,.....,S\n"
3305 "sss|,.....,.....,.....,S\n"
3306 "sss|,.....,.....,.....,S\n"
3307 "sss|....................\n"
3308 "sss|....................\n"
3309 "sss|....................\n"
3310 "sss|....................\n"
3311 "sss|....................\n"
3312 "sss|....................\n"
3313 "sss|...,,...,....,....,S\n"
3314 "sss|..,,,,..,....,....,S\n"
3315 "sss|...,,...,....,....,S\n"
3316 "sss|...,,...,....,....,S\n"
3317 "sss|........,....,....,S\n"
3318 "sss|........,....,....,S\n"
3319 "sss|........|---|---|HHG\n"
3320 "sss|........|.R<|EEE|___\n"
3321 "sss|........|.R.|EEED___\n", b_ter_key, b_fur_key );
3322 if( dat.monster_density() > 1 ) {
3324 } else {
3326 }
3327 if( dat.west() == "office_tower_b_entrance" ) {
3328 rotate( 1 );
3329 if( x_in_y( 1, 5 ) ) {
3330 add_vehicle( vproto_id( "car" ), point( 17, 7 ), 180_degrees );
3331 }
3332 if( x_in_y( 1, 3 ) ) {
3333 add_vehicle( vproto_id( "motorcycle" ), point( 17, 13 ), 180_degrees );
3334 }
3335 if( x_in_y( 1, 5 ) ) {
3336 if( one_in( 3 ) ) {
3337 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3338 } else {
3339 add_vehicle( vproto_id( "pickup" ), point( 17, 19 ), 180_degrees );
3340 }
3341 }
3342 } else if( dat.north() == "office_tower_b_entrance" ) {
3343 rotate( 2 );
3344 if( x_in_y( 1, 5 ) ) {
3345 add_vehicle( vproto_id( "car" ), point( 10, 17 ), 270_degrees );
3346 }
3347 if( x_in_y( 1, 3 ) ) {
3348 add_vehicle( vproto_id( "motorcycle" ), point( 4, 18 ), 270_degrees );
3349 }
3350 if( x_in_y( 1, 5 ) ) {
3351 if( one_in( 3 ) ) {
3352 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3353 } else {
3354 add_vehicle( vproto_id( "pickup" ), point( 16, 17 ), 270_degrees );
3355 }
3356 }
3357 } else if( dat.east() == "office_tower_b_entrance" ) {
3358 rotate( 3 );
3359 if( x_in_y( 1, 5 ) ) {
3360 add_vehicle( vproto_id( "car" ), point( 6, 4 ), 0_degrees );
3361 }
3362 if( x_in_y( 1, 3 ) ) {
3363 add_vehicle( vproto_id( "motorcycle" ), point( 6, 10 ), 180_degrees );
3364 }
3365 if( x_in_y( 1, 5 ) ) {
3366 add_vehicle( vproto_id( "pickup" ), point( 6, 16 ), 0_degrees );
3367 }
3368
3369 } else {
3370 if( x_in_y( 1, 5 ) ) {
3371 add_vehicle( vproto_id( "pickup" ), point( 7, 6 ), 90_degrees );
3372 }
3373 if( x_in_y( 1, 5 ) ) {
3374 add_vehicle( vproto_id( "car" ), point( 14, 6 ), 90_degrees );
3375 }
3376 if( x_in_y( 1, 3 ) ) {
3377 add_vehicle( vproto_id( "motorcycle" ), point( 19, 6 ), 90_degrees );
3378 }
3379 }
3380 } else if( ( dat.west() == "office_tower_b_entrance" && dat.north() == "office_tower_b" ) ||
3381 ( dat.north() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3382 ( dat.west() == "office_tower_b" && dat.south() == "office_tower_b_entrance" ) ||
3383 ( dat.south() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ) {
3385 "___DEEE|...|...,,...|sss\n"
3386 "___|EEE|...|..,,,,..|sss\n"
3387 "GHH|---|-+-|...,,...|sss\n"
3388 "....................|sss\n"
3389 "....................|sss\n"
3390 "....................|sss\n"
3391 "....................|sss\n"
3392 "....................|sss\n"
3393 "....................|sss\n"
3394 "....................|sss\n"
3395 "....................|sss\n"
3396 "|...................|sss\n"
3397 "|...................|sss\n"
3398 "|,.....,.....,.....,|sss\n"
3399 "|,.....,.....,.....,|sss\n"
3400 "|,.....,.....,.....,|sss\n"
3401 "|,.....,.....,.....,|sss\n"
3402 "|,.....,.....,.....,|sss\n"
3403 "|,.....,.....,.....,|sss\n"
3404 "|-------------------|sss\n"
3405 "ssssssssssssssssssssssss\n"
3406 "ssssssssssssssssssssssss\n"
3407 "ssssssssssssssssssssssss\n"
3408 "ssssssssssssssssssssssss\n", b_ter_key, b_fur_key );
3409 if( dat.monster_density() > 1 ) {
3411 } else {
3413 }
3414 if( dat.north() == "office_tower_b_entrance" ) {
3415 rotate( 1 );
3416 if( x_in_y( 1, 5 ) ) {
3417 add_vehicle( vproto_id( "car" ), point( 8, 15 ), 0_degrees );
3418 }
3419 if( x_in_y( 1, 5 ) ) {
3420 add_vehicle( vproto_id( "pickup" ), point( 7, 10 ), 180_degrees );
3421 }
3422 if( x_in_y( 1, 3 ) ) {
3423 add_vehicle( vproto_id( "beetle" ), point( 7, 3 ), 0_degrees );
3424 }
3425 } else if( dat.east() == "office_tower_b_entrance" ) {
3426 rotate( 2 );
3427 if( x_in_y( 1, 5 ) ) {
3428 if( one_in( 3 ) ) {
3429 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3430 } else {
3431 add_vehicle( vproto_id( "pickup" ), point( 7, 7 ), 270_degrees );
3432 }
3433 }
3434 if( x_in_y( 1, 5 ) ) {
3435 add_vehicle( vproto_id( "car" ), point( 13, 8 ), 90_degrees );
3436 }
3437 if( x_in_y( 1, 3 ) ) {
3438 add_vehicle( vproto_id( "beetle" ), point( 20, 7 ), 90_degrees );
3439 }
3440 } else if( dat.south() == "office_tower_b_entrance" ) {
3441 rotate( 3 );
3442 if( x_in_y( 1, 5 ) ) {
3443 add_vehicle( vproto_id( "pickup" ), point( 16, 7 ), 0_degrees );
3444 }
3445 if( x_in_y( 1, 5 ) ) {
3446 add_vehicle( vproto_id( "car" ), point( 15, 13 ), 180_degrees );
3447 }
3448 if( x_in_y( 1, 3 ) ) {
3449 add_vehicle( vproto_id( "beetle" ), point( 15, 20 ), 180_degrees );
3450 }
3451 } else {
3452 if( x_in_y( 1, 5 ) ) {
3453 add_vehicle( vproto_id( "pickup" ), point( 16, 16 ), 90_degrees );
3454 }
3455 if( x_in_y( 1, 5 ) ) {
3456 add_vehicle( vproto_id( "car" ), point( 9, 15 ), 270_degrees );
3457 }
3458 if( x_in_y( 1, 3 ) ) {
3459 add_vehicle( vproto_id( "beetle" ), point( 4, 16 ), 270_degrees );
3460 }
3461 }
3462 } else {
3464 "ssssssssssssssssssssssss\n"
3465 "ssssssssssssssssssssssss\n"
3466 "--------------------|sss\n"
3467 "S,.....,.....,.....,|sss\n"
3468 "S,.....,.....,.....,|sss\n"
3469 "S,.....,.....,.....,|sss\n"
3470 "S,.....,.....,.....,|sss\n"
3471 "S,.....,.....,.....,|sss\n"
3472 "S,.....,.....,.....,|sss\n"
3473 "....................|sss\n"
3474 "....................|sss\n"
3475 "....................|sss\n"
3476 "....................|sss\n"
3477 "....................|sss\n"
3478 "....................|sss\n"
3479 "S,....,....,........|sss\n"
3480 "S,....,....,........|sss\n"
3481 "S,....,....,........|sss\n"
3482 "S,....,....,........|sss\n"
3483 "S,....,....,........|sss\n"
3484 "S,....,....,........|sss\n"
3485 "GHH|---|---|........|sss\n"
3486 "___|xEE|.R<|........|sss\n"
3487 "___DEEE|.R.|...,,...|sss\n", b_ter_key, b_fur_key );
3488 if( dat.monster_density() > 1 ) {
3490 } else {
3492 }
3493 if( dat.west() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3494 rotate( 1 );
3495 if( x_in_y( 1, 5 ) ) {
3496 if( one_in( 3 ) ) {
3497 add_vehicle( vproto_id( "cube_van" ), point( 17, 4 ), 180_degrees );
3498 } else {
3499 add_vehicle( vproto_id( "cube_van_cheap" ), point( 17, 4 ), 180_degrees );
3500 }
3501 }
3502 if( x_in_y( 1, 5 ) ) {
3503 add_vehicle( vproto_id( "pickup" ), point( 17, 10 ), 180_degrees );
3504 }
3505 if( x_in_y( 1, 3 ) ) {
3506 add_vehicle( vproto_id( "car" ), point( 17, 17 ), 180_degrees );
3507 }
3508 } else if( dat.east() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3509 rotate( 2 );
3510 if( x_in_y( 1, 5 ) ) {
3511 if( one_in( 3 ) ) {
3512 add_vehicle( vproto_id( "cube_van" ), point( 6, 17 ), 270_degrees );
3513 } else {
3514 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 17 ), 270_degrees );
3515 }
3516 }
3517 if( x_in_y( 1, 5 ) ) {
3518 add_vehicle( vproto_id( "pickup" ), point( 12, 17 ), 270_degrees );
3519 }
3520 if( x_in_y( 1, 3 ) ) {
3521 add_vehicle( vproto_id( "fire_truck" ), point( 18, 17 ), 270_degrees );
3522 }
3523 } else if( dat.east() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3524 rotate( 3 );
3525 if( x_in_y( 1, 5 ) ) {
3526 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 6 ), 0_degrees );
3527 }
3528 if( x_in_y( 1, 5 ) ) {
3529 if( one_in( 3 ) ) {
3530 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3531 } else {
3532 add_vehicle( vproto_id( "pickup" ), point( 6, 13 ), 0_degrees );
3533 }
3534 }
3535 if( x_in_y( 1, 3 ) ) {
3536 add_vehicle( vproto_id( "car" ), point( 5, 19 ), 180_degrees );
3537 }
3538 } else {
3539 if( x_in_y( 1, 5 ) ) {
3540 add_vehicle( vproto_id( "flatbed_truck" ), point( 16, 6 ), 90_degrees );
3541 }
3542 if( x_in_y( 1, 5 ) ) {
3543 add_vehicle( vproto_id( "cube_van_cheap" ), point( 10, 6 ), 90_degrees );
3544 }
3545 if( x_in_y( 1, 3 ) ) {
3546 add_vehicle( vproto_id( "car" ), point( 4, 6 ), 90_degrees );
3547 }
3548 }
3549 }
3550 }
3551}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
void fill_groundcover()
Definition: mapgendata.cpp:125
float monster_density() const
Definition: mapgendata.h:90
furn_id f_chair
Definition: mapdata.cpp:1106
ter_id t_door_locked_alarm
Definition: mapdata.cpp:660
furn_id f_fridge
Definition: mapdata.cpp:1109
ter_id t_wall
Definition: mapdata.cpp:649
furn_id f_table
Definition: mapdata.cpp:1107
furn_id f_bookcase
Definition: mapdata.cpp:1110
ter_id t_pavement
Definition: mapdata.cpp:633
furn_id f_desk
Definition: mapdata.cpp:1106
ter_id t_railing
Definition: mapdata.cpp:691
furn_id f_indoor_plant
Definition: mapdata.cpp:1103
furn_id f_counter
Definition: mapdata.cpp:1108
furn_id f_rack
Definition: mapdata.cpp:1110
ter_id t_pavement_y
Definition: mapdata.cpp:633
ter_id t_wall_glass
Definition: mapdata.cpp:651
furn_id f_crate_c
Definition: mapdata.cpp:1113
furn_id f_toilet
Definition: mapdata.cpp:1104
ter_id t_window
Definition: mapdata.cpp:669
furn_id f_bench
Definition: mapdata.cpp:1107
ter_id t_door_glass_c
Definition: mapdata.cpp:667
ter_id t_console_broken
Definition: mapdata.cpp:707
ter_id t_door_locked
Definition: mapdata.cpp:660
furn_id f_locker
Definition: mapdata.cpp:1109
ter_id t_elevator
Definition: mapdata.cpp:726
furn_id f_sink
Definition: mapdata.cpp:1105
ter_id t_door_c
Definition: mapdata.cpp:659
static const mongroup_id GROUP_ZOMBIE_COP("GROUP_ZOMBIE_COP")
static const mongroup_id GROUP_PLAIN("GROUP_PLAIN")
static const mongroup_id GROUP_ZOMBIE("GROUP_ZOMBIE")
format_effect< furn_id > furn_bind(const char(&characters)[N], Args... ids)
Definition: mapgenformat.h:76
void formatted_set_simple(map *m, point start, const char *cstr, const format_effect< ter_id > &ter_b, const format_effect< furn_id > &furn_b)
Set terrain and furniture on the supplied map.
format_effect< ter_id > ter_bind(const char(&characters)[N], Args... ids)
The functions create a mapping of characters to ids, usable with formatted_set_simple.
Definition: mapgenformat.h:66
string_id< vehicle_prototype > vproto_id
Definition: type_id.h:196

References add_vehicle(), mapgendata::east(), EAST_EDGE, f_bench, f_bookcase, f_chair, f_counter, f_crate_c, f_desk, f_fridge, f_indoor_plant, f_locker, f_null, f_rack, f_sink, f_table, f_toilet, mapgendata::fill_groundcover(), mapf::formatted_set_simple(), mapf::furn_bind(), GROUP_PLAIN, GROUP_ZOMBIE, GROUP_ZOMBIE_COP, mapgendata::monster_density(), mapgendata::north(), one_in(), place_items(), place_spawns(), point_zero, rng(), rotate(), mapgendata::south(), SOUTH_EDGE, spawn_item(), calendar::start_of_cataclysm, t_console, t_console_broken, t_door_c, t_door_glass_c, t_door_locked, t_door_locked_alarm, t_door_metal_locked, t_elevator, t_floor, t_pavement, t_pavement_y, t_railing, t_rock, t_shrub, t_sidewalk, t_stairs_down, t_stairs_up, t_wall, t_wall_glass, t_window, mapf::ter_bind(), mapgendata::terrain_type(), mapgendata::west(), and x_in_y().

Referenced by draw_map().

◆ draw_rough_circle_furn()

void map::draw_rough_circle_furn ( const furn_id type,
point  p,
int  rad 
)

Definition at line 8575 of file map.cpp.

8576{
8577 draw_rough_circle( [this, type]( point q ) {
8578 this->furn_set( q, type );
8579 }, p, rad );
8580}

References draw_rough_circle(), furn_set(), rad, and type.

Referenced by rough_circle_furn().

◆ draw_rough_circle_ter()

void map::draw_rough_circle_ter ( const ter_id type,
point  p,
int  rad 
)

Definition at line 8568 of file map.cpp.

8569{
8570 draw_rough_circle( [this, type]( point q ) {
8571 this->ter_set( q, type );
8572 }, p, rad );
8573}

References draw_rough_circle(), rad, ter_set(), and type.

Referenced by rough_circle().

◆ draw_slimepit()

void map::draw_slimepit ( mapgendata dat)
protected

Definition at line 4882 of file mapgen.cpp.

4883{
4884 const oter_id &terrain_type = dat.terrain_type();
4885 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ) {
4886 for( int i = 0; i < SEEX * 2; i++ ) {
4887 for( int j = 0; j < SEEY * 2; j++ ) {
4888 if( !one_in( 10 ) && ( j < dat.n_fac * SEEX ||
4889 i < dat.w_fac * SEEX ||
4890 j > SEEY * 2 - dat.s_fac * SEEY ||
4891 i > SEEX * 2 - dat.e_fac * SEEX ) ) {
4892 ter_set( point( i, j ), ( !one_in( 10 ) ? t_slime : t_rock_floor ) );
4893 } else if( rng( 0, SEEX ) > std::abs( i - SEEX ) && rng( 0, SEEY ) > std::abs( j - SEEY ) ) {
4894 ter_set( point( i, j ), t_slime );
4895 } else if( dat.zlevel() == 0 ) {
4896 ter_set( point( i, j ), t_dirt );
4897 } else {
4898 ter_set( point( i, j ), t_rock_floor );
4899 }
4900 }
4901 }
4902 if( terrain_type == "slimepit_down" ) {
4903 ter_set( point( rng( 3, SEEX * 2 - 4 ), rng( 3, SEEY * 2 - 4 ) ), t_slope_down );
4904 }
4905 if( dat.above() == "slimepit_down" ) {
4906 switch( rng( 1, 4 ) ) {
4907 case 1:
4908 ter_set( point( rng( 0, 2 ), rng( 0, 2 ) ), t_slope_up );
4909 break;
4910 case 2:
4911 ter_set( point( rng( 0, 2 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
4912 break;
4913 case 3:
4914 ter_set( point( SEEX * 2 - rng( 1, 3 ), rng( 0, 2 ) ), t_slope_up );
4915 break;
4916 case 4:
4917 ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
4918 }
4919 }
4920 place_spawns( GROUP_BLOB, 1, point( SEEX, SEEY ), point( SEEX, SEEY ), 0.15 );
4921 place_items( item_group_id( "sewer" ), 40, point_zero, point( EAST_EDGE, SOUTH_EDGE ), true,
4923 }
4924}
static const mongroup_id GROUP_BLOB("GROUP_BLOB")

References mapgendata::above(), mapgendata::e_fac, EAST_EDGE, GROUP_BLOB, is_ot_match(), mapgendata::n_fac, one_in(), place_items(), place_spawns(), point_zero, prefix, rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH_EDGE, calendar::start_of_cataclysm, t_dirt, t_rock_floor, t_slime, t_slope_down, t_slope_up, ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_square_furn()

void map::draw_square_furn ( const furn_id type,
point  p1,
point  p2 
)

Definition at line 8545 of file map.cpp.

8546{
8547 draw_square( [this, type]( point p ) {
8548 this->furn_set( p, type );
8549 }, p1, p2 );
8550}
void draw_square(std::function< void(point)>set, point p1, point p2)

References draw_square(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and square_furn().

◆ draw_square_ter() [1/3]

◆ draw_square_ter() [2/3]

void map::draw_square_ter ( const weighted_int_list< ter_id > &  f,
point  p1,
point  p2 
)

Definition at line 8559 of file map.cpp.

8561{
8562 draw_square( [this, f]( point p ) {
8563 const ter_id *tid = f.pick();
8564 this->ter_set( p, tid != nullptr ? *tid : t_null );
8565 }, p1, p2 );
8566}
ter_id t_null
Definition: mapdata.cpp:626
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References draw_square(), weighted_list< W, T >::pick(), t_null, and ter_set().

◆ draw_square_ter() [3/3]

void map::draw_square_ter ( ter_id(*)()  f,
point  p1,
point  p2 
)

Definition at line 8552 of file map.cpp.

8553{
8554 draw_square( [this, f]( point p ) {
8555 this->ter_set( p, f() );
8556 }, p1, p2 );
8557}

References draw_square(), and ter_set().

◆ draw_temple()

void map::draw_temple ( mapgendata dat)
protected

Definition at line 4350 of file mapgen.cpp.

4351{
4352 const oter_id &terrain_type = dat.terrain_type();
4353 if( terrain_type == "temple" || terrain_type == "temple_stairs" ) {
4354 if( dat.zlevel() == 0 ) {
4355 // Ground floor
4356 // TODO: More varieties?
4357 fill_background( this, t_dirt );
4358 square( this, t_grate, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEX ) );
4359 ter_set( point( SEEX + 1, SEEY + 1 ), t_pedestal_temple );
4360 } else {
4361 // Underground! Shit's about to get interesting!
4362 // Start with all rock floor
4364 // We always start at the south and go north.
4365 // We use (y / 2 + z) % 4 to guarantee that rooms don't repeat.
4366 switch( 1 + std::abs( abs_sub.y / 2 + dat.zlevel() + 4 ) % 4 ) { // TODO: More varieties!
4367
4368 case 1:
4369 // Flame bursts
4370 square( this, t_rock, point_zero, point( SEEX - 1, SOUTH_EDGE ) );
4371 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, SOUTH_EDGE ) );
4372 for( int i = 2; i < SEEY * 2 - 4; i++ ) {
4373 add_field( {SEEX, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4374 add_field( {SEEX + 1, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4375 }
4376 break;
4377
4378 case 2:
4379 // Spreading water
4380 square( this, t_water_dp, point( 4, 4 ), point( 5, 5 ) );
4381 // replaced mon_sewer_snake spawn with GROUP_SEWER
4382 // Decide whether a group of only sewer snakes be made, probably not worth it
4383 place_spawns( GROUP_SEWER, 1, point( 4, 4 ), point( 4, 4 ), 1, true );
4384
4385 square( this, t_water_dp, point( SEEX * 2 - 5, 4 ), point( SEEX * 2 - 4, 6 ) );
4386 place_spawns( GROUP_SEWER, 1, point( 1, SEEX * 2 - 5 ), point( 1, SEEX * 2 - 5 ), 1, true );
4387
4388 square( this, t_water_dp, point( 4, SEEY * 2 - 5 ), point( 6, SEEY * 2 - 4 ) );
4389
4390 square( this, t_water_dp, point( SEEX * 2 - 5, SEEY * 2 - 5 ), point( SEEX * 2 - 4,
4391 SEEY * 2 - 4 ) );
4392
4393 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4394 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4395 line( this, t_grate, point( SEEX, 1 ), point( SEEX + 1, 1 ) ); // To drain the water
4396 mtrap_set( this, point( SEEX, SEEY * 2 - 2 ), tr_temple_flood );
4397 mtrap_set( this, point( SEEX + 1, SEEY * 2 - 2 ), tr_temple_flood );
4398 for( int y = 2; y < SEEY * 2 - 2; y++ ) {
4399 for( int x = 2; x < SEEX * 2 - 2; x++ ) {
4400 if( ter( point( x, y ) ) == t_rock_floor && one_in( 4 ) ) {
4401 mtrap_set( this, point( x, y ), tr_temple_flood );
4402 }
4403 }
4404 }
4405 break;
4406
4407 case 3: { // Flipping walls puzzle
4408 line( this, t_rock, point_zero, point( SEEX - 1, 0 ) );
4409 line( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 0 ) );
4410 line( this, t_rock, point( SEEX - 1, 1 ), point( SEEX - 1, 6 ) );
4411 line( this, t_bars, point( SEEX + 2, 1 ), point( SEEX + 2, 6 ) );
4412 ter_set( point( 14, 1 ), t_switch_rg );
4413 ter_set( point( 15, 1 ), t_switch_gb );
4414 ter_set( point( 16, 1 ), t_switch_rb );
4415 ter_set( point( 17, 1 ), t_switch_even );
4416 // Start with clear floors--then work backwards to the starting state
4417 line( this, t_floor_red, point( SEEX, 1 ), point( SEEX + 1, 1 ) );
4418 line( this, t_floor_green, point( SEEX, 2 ), point( SEEX + 1, 2 ) );
4419 line( this, t_floor_blue, point( SEEX, 3 ), point( SEEX + 1, 3 ) );
4420 line( this, t_floor_red, point( SEEX, 4 ), point( SEEX + 1, 4 ) );
4421 line( this, t_floor_green, point( SEEX, 5 ), point( SEEX + 1, 5 ) );
4422 line( this, t_floor_blue, point( SEEX, 6 ), point( SEEX + 1, 6 ) );
4423 // Now, randomly choose actions
4424 // Set up an actions vector so that there's not undue repetition
4425 std::vector<int> actions;
4426 actions.push_back( 1 );
4427 actions.push_back( 2 );
4428 actions.push_back( 3 );
4429 actions.push_back( 4 );
4430 actions.push_back( rng( 1, 3 ) );
4431 while( !actions.empty() ) {
4432 const int action = random_entry_removed( actions );
4433 for( int y = 1; y < 7; y++ ) {
4434 for( int x = SEEX; x <= SEEX + 1; x++ ) {
4435 switch( action ) {
4436 case 1:
4437 // Toggle RG
4438 if( ter( point( x, y ) ) == t_floor_red ) {
4439 ter_set( point( x, y ), t_rock_red );
4440 } else if( ter( point( x, y ) ) == t_rock_red ) {
4441 ter_set( point( x, y ), t_floor_red );
4442 } else if( ter( point( x, y ) ) == t_floor_green ) {
4443 ter_set( point( x, y ), t_rock_green );
4444 } else if( ter( point( x, y ) ) == t_rock_green ) {
4445 ter_set( point( x, y ), t_floor_green );
4446 }
4447 break;
4448 case 2:
4449 // Toggle GB
4450 if( ter( point( x, y ) ) == t_floor_blue ) {
4451 ter_set( point( x, y ), t_rock_blue );
4452 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4453 ter_set( point( x, y ), t_floor_blue );
4454 } else if( ter( point( x, y ) ) == t_floor_green ) {
4455 ter_set( point( x, y ), t_rock_green );
4456 } else if( ter( point( x, y ) ) == t_rock_green ) {
4457 ter_set( point( x, y ), t_floor_green );
4458 }
4459 break;
4460 case 3:
4461 // Toggle RB
4462 if( ter( point( x, y ) ) == t_floor_blue ) {
4463 ter_set( point( x, y ), t_rock_blue );
4464 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4465 ter_set( point( x, y ), t_floor_blue );
4466 } else if( ter( point( x, y ) ) == t_floor_red ) {
4467 ter_set( point( x, y ), t_rock_red );
4468 } else if( ter( point( x, y ) ) == t_rock_red ) {
4469 ter_set( point( x, y ), t_floor_red );
4470 }
4471 break;
4472 case 4:
4473 // Toggle Even
4474 if( y % 2 == 0 ) {
4475 if( ter( point( x, y ) ) == t_floor_blue ) {
4476 ter_set( point( x, y ), t_rock_blue );
4477 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4478 ter_set( point( x, y ), t_floor_blue );
4479 } else if( ter( point( x, y ) ) == t_floor_red ) {
4480 ter_set( point( x, y ), t_rock_red );
4481 } else if( ter( point( x, y ) ) == t_rock_red ) {
4482 ter_set( point( x, y ), t_floor_red );
4483 } else if( ter( point( x, y ) ) == t_floor_green ) {
4484 ter_set( point( x, y ), t_rock_green );
4485 } else if( ter( point( x, y ) ) == t_rock_green ) {
4486 ter_set( point( x, y ), t_floor_green );
4487 }
4488 }
4489 break;
4490 }
4491 }
4492 }
4493 }
4494 }
4495 break;
4496
4497 case 4: { // Toggling walls maze
4498 square( this, t_rock, point_zero, point( SEEX - 1, 1 ) );
4499 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4500 square( this, t_rock, point( 0, 2 ), point( SEEX - 4, SEEY * 2 - 3 ) );
4501 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 1 ) );
4502 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4503 square( this, t_rock, point( SEEX + 5, 2 ), point( EAST_EDGE, SEEY * 2 - 3 ) );
4504 int x = rng( SEEX - 1, SEEX + 2 ), y = 2;
4505 std::vector<point> path; // Path, from end to start
4506 while( x < SEEX - 1 || x > SEEX + 2 || y < SEEY * 2 - 2 ) {
4507 static const std::vector<ter_id> terrains = {
4509 };
4510 path.push_back( point( x, y ) );
4511 ter_set( point( x, y ), random_entry( terrains ) );
4512 if( y == SEEY * 2 - 2 ) {
4513 if( x < SEEX - 1 ) {
4514 x++;
4515 } else if( x > SEEX + 2 ) {
4516 x--;
4517 }
4518 } else {
4519 std::vector<point> next;
4520 for( int nx = x - 1; nx <= x + 1; nx++ ) {
4521 for( int ny = y; ny <= y + 1; ny++ ) {
4522 if( ter( point( nx, ny ) ) == t_rock_floor ) {
4523 next.push_back( point( nx, ny ) );
4524 }
4525 }
4526 }
4527 if( next.empty() ) {
4528 break;
4529 } else {
4530 const point p = random_entry( next );
4531 x = p.x;
4532 y = p.y;
4533 }
4534 }
4535 }
4536 // Now go backwards through path (start to finish), toggling any tiles that need
4537 bool toggle_red = false;
4538 bool toggle_green = false;
4539 bool toggle_blue = false;
4540 for( int i = path.size() - 1; i >= 0; i-- ) {
4541 if( ter( path[i] ) == t_floor_red ) {
4542 toggle_green = !toggle_green;
4543 if( toggle_red ) {
4544 ter_set( path[i], t_rock_red );
4545 }
4546 } else if( ter( path[i] ) == t_floor_green ) {
4547 toggle_blue = !toggle_blue;
4548 if( toggle_green ) {
4549 ter_set( path[i], t_rock_green );
4550 }
4551 } else if( ter( path[i] ) == t_floor_blue ) {
4552 toggle_red = !toggle_red;
4553 if( toggle_blue ) {
4554 ter_set( path[i], t_rock_blue );
4555 }
4556 }
4557 }
4558 // Finally, fill in the rest with random tiles, and place toggle traps
4559 for( int i = SEEX - 3; i <= SEEX + 4; i++ ) {
4560 for( int j = 2; j <= SEEY * 2 - 2; j++ ) {
4561 mtrap_set( this, point( i, j ), tr_temple_toggle );
4562 if( ter( point( i, j ) ) == t_rock_floor ) {
4563 static const std::vector<ter_id> terrains = {
4566 };
4567 ter_set( point( i, j ), random_entry( terrains ) );
4568 }
4569 }
4570 }
4571 }
4572 break;
4573 } // Done with room type switch
4574 // Stairs down if we need them
4575 if( terrain_type == "temple_stairs" ) {
4576 line( this, t_stairs_down, point( SEEX, 0 ), point( SEEX + 1, 0 ) );
4577 }
4578 // Stairs at the south if dat.above() has stairs down.
4579 if( dat.above() == "temple_stairs" ) {
4580 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4581 }
4582
4583 } // Done with underground-only stuff
4584 } else if( terrain_type == "temple_finale" ) {
4585 fill_background( this, t_rock );
4586 square( this, t_rock_floor, point( SEEX - 1, 1 ), point( SEEX + 2, 4 ) );
4587 square( this, t_rock_floor, point( SEEX, 5 ), point( SEEX + 1, SOUTH_EDGE ) );
4588 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4589 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4590 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4591 return;
4592
4593 }
4594}
@ action
Definition: dialogue.h:36
ter_id t_switch_even
Definition: mapdata.cpp:730
ter_id t_rock_red
Definition: mapdata.cpp:729
ter_id t_pedestal_temple
Definition: mapdata.cpp:727
ter_id t_floor_blue
Definition: mapdata.cpp:729
ter_id t_grate
Definition: mapdata.cpp:639
ter_id t_switch_rb
Definition: mapdata.cpp:730
ter_id t_rock_green
Definition: mapdata.cpp:729
ter_id t_rock_blue
Definition: mapdata.cpp:729
ter_id t_floor_green
Definition: mapdata.cpp:729
ter_id t_switch_gb
Definition: mapdata.cpp:730
ter_id t_floor_red
Definition: mapdata.cpp:729
ter_id t_switch_rg
Definition: mapdata.cpp:730
static const mongroup_id GROUP_SEWER("GROUP_SEWER")
static const trap_str_id tr_temple_flood("tr_temple_flood")
generic_factory< oter_t > terrains("overmap terrain")
V random_entry_removed(C &container)
Returns a random entry in the container and removes it from the container.
Definition: rng.h:170
trap_id tr_temple_toggle
Definition: trap.cpp:311

References mapgendata::above(), abs_sub, action, add_field(), EAST_EDGE, fd_fire_vent, fill_background(), GROUP_SEWER, line(), mtrap_set(), one_in(), place_spawns(), point_zero, random_entry(), random_entry_removed(), rng(), SEEX, SEEY, SOUTH_EDGE, spawn_artifact(), square(), t_bars, t_dirt, t_floor_blue, t_floor_green, t_floor_red, t_grate, t_pedestal_temple, t_rock, t_rock_blue, t_rock_floor, t_rock_green, t_rock_red, t_stairs_down, t_stairs_up, t_switch_even, t_switch_gb, t_switch_rb, t_switch_rg, t_water_dp, ter(), ter_set(), mapgendata::terrain_type(), anonymous_namespace{overmap.cpp}::terrains, tr_temple_flood, tr_temple_toggle, point::x, point::y, tripoint::y, tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_triffid()

void map::draw_triffid ( mapgendata dat)
protected

Definition at line 4926 of file mapgen.cpp.

4927{
4928 const oter_id &terrain_type = dat.terrain_type();
4929 if( terrain_type == "triffid_roots" ) {
4931 int node = 0;
4932 int step = 0;
4933 bool node_built[16];
4934 bool done = false;
4935 for( auto &elem : node_built ) {
4936 elem = false;
4937 }
4938 do {
4939 node_built[node] = true;
4940 step++;
4941 point node2( 1 + 6 * ( node % 4 ), 1 + 6 * static_cast<int>( node / 4 ) );
4942 // Clear a 4x4 dirt square
4943 square( this, t_dirt, node2, node2 + point( 3, 3 ) );
4944 // Spawn a monster in there
4945 if( step > 2 ) { // First couple of chambers are safe
4946 int monrng = rng( 1, 25 );
4947 point spawn( node2 + point{ rng( 0, 3 ), rng( 0, 3 ) } );
4948 if( monrng <= 24 ) {
4950 node2 + point( 3, 3 ), 1, true );
4951 } else {
4952 for( int webx = node2.x; webx <= node2.x + 3; webx++ ) {
4953 for( int weby = node2.y; weby <= node2.y + 3; weby++ ) {
4954 add_field( {webx, weby, abs_sub.z}, fd_web, rng( 1, 3 ) );
4955 }
4956 }
4957 place_spawns( GROUP_SPIDER, 1, spawn, spawn, 1, true );
4958 }
4959 }
4960 // TODO: Non-monster hazards?
4961 // Next, pick a cell to move to
4962 std::vector<direction> move;
4963 if( node % 4 > 0 && !node_built[node - 1] ) {
4964 move.push_back( direction::WEST );
4965 }
4966 if( node % 4 < 3 && !node_built[node + 1] ) {
4967 move.push_back( direction::EAST );
4968 }
4969 if( static_cast<int>( node / 4 ) > 0 && !node_built[node - 4] ) {
4970 move.push_back( direction::NORTH );
4971 }
4972 if( static_cast<int>( node / 4 ) < 3 && !node_built[node + 4] ) {
4973 move.push_back( direction::SOUTH );
4974 }
4975
4976 if( move.empty() ) { // Nowhere to go!
4977 square( this, t_slope_down, node2 + point_south_east, node2 + point( 2, 2 ) );
4978 done = true;
4979 } else {
4980 switch( random_entry( move ) ) {
4981 case direction::NORTH:
4982 square( this, t_dirt, node2 + point( 1, -2 ), node2 + point( 2, -1 ) );
4983 node -= 4;
4984 break;
4985 case direction::EAST:
4986 square( this, t_dirt, node2 + point( 4, 1 ), node2 + point( 5, 2 ) );
4987 node++;
4988 break;
4989 case direction::SOUTH:
4990 square( this, t_dirt, node2 + point( 1, 4 ), node2 + point( 2, 5 ) );
4991 node += 4;
4992 break;
4993 case direction::WEST:
4994 square( this, t_dirt, node2 + point( -2, 1 ), node2 + point( -1, 2 ) );
4995 node--;
4996 break;
4997 default:
4998 break;
4999 }
5000 }
5001 } while( !done );
5002 square( this, t_slope_up, point( 2, 2 ), point( 3, 3 ) );
5003 rotate( rng( 0, 3 ) );
5004 } else if( terrain_type == "triffid_finale" ) {
5006 // NOLINTNEXTLINE(cata-use-named-point-constants)
5007 square( this, t_dirt, point( 1, 1 ), point( 4, 4 ) );
5008 square( this, t_dirt, point( 19, 19 ), point( 22, 22 ) );
5009 // Drunken walk until we reach the heart (lower right, [19, 19])
5010 // Chance increases by 1 each turn, and gives the % chance of forcing a move
5011 // to the right or down.
5012 int chance = 0;
5013 int x = 4;
5014 int y = 4;
5015 do {
5016 ter_set( point( x, y ), t_dirt );
5017
5018 if( chance >= 10 && one_in( 10 ) ) { // Add a spawn
5019 place_spawns( GROUP_TRIFFID, 1, point( x, y ), point( x, y ), 1, true );
5020 }
5021
5022 if( rng( 0, 99 ) < chance ) { // Force movement down or to the right
5023 if( x >= 19 ) {
5024 y++;
5025 } else if( y >= 19 ) {
5026 x++;
5027 } else {
5028 if( one_in( 2 ) ) {
5029 x++;
5030 } else {
5031 y++;
5032 }
5033 }
5034 } else {
5035 chance++; // Increase chance of forced movement down/right
5036 // Weigh movement towards directions with lots of existing walls
5037 int chance_west = 0;
5038 int chance_east = 0;
5039 int chance_north = 0;
5040 int chance_south = 0;
5041 for( int dist = 1; dist <= 5; dist++ ) {
5042 if( ter( point( x - dist, y ) ) == t_root_wall ) {
5043 chance_west++;
5044 }
5045 if( ter( point( x + dist, y ) ) == t_root_wall ) {
5046 chance_east++;
5047 }
5048 if( ter( point( x, y - dist ) ) == t_root_wall ) {
5049 chance_north++;
5050 }
5051 if( ter( point( x, y + dist ) ) == t_root_wall ) {
5052 chance_south++;
5053 }
5054 }
5055 int roll = rng( 0, chance_west + chance_east + chance_north + chance_south );
5056 if( roll < chance_west && x > 0 ) {
5057 x--;
5058 } else if( roll < chance_west + chance_east && x < EAST_EDGE ) {
5059 x++;
5060 } else if( roll < chance_west + chance_east + chance_north && y > 0 ) {
5061 y--;
5062 } else if( y < SOUTH_EDGE ) {
5063 y++;
5064 }
5065 } // Done with drunken walk
5066 } while( x < 19 || y < 19 );
5067 // NOLINTNEXTLINE(cata-use-named-point-constants)
5068 square( this, t_slope_up, point( 1, 1 ), point( 2, 2 ) );
5069 place_spawns( GROUP_TRIFFID_HEART, 1, point( 21, 21 ), point( 21, 21 ), 1, true );
5070
5071 }
5072}
ter_id t_root_wall
Definition: mapdata.cpp:687
static const mongroup_id GROUP_TRIFFID_OUTER("GROUP_TRIFFID_OUTER")
static const mongroup_id GROUP_SPIDER("GROUP_SPIDER")
static const mongroup_id GROUP_TRIFFID("GROUP_TRIFFID")
static const mongroup_id GROUP_TRIFFID_HEART("GROUP_TRIFFID_HEART")

References abs_sub, add_field(), detail::digits::done, EAST, EAST_EDGE, fd_web, fill_background(), GROUP_SPIDER, GROUP_TRIFFID, GROUP_TRIFFID_HEART, GROUP_TRIFFID_OUTER, avatar_action::move(), NORTH, one_in(), place_spawns(), point_south_east, random_entry(), rng(), rotate(), SOUTH, SOUTH_EDGE, square(), t_dirt, t_root_wall, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), WEST, point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ drawsq()

void map::drawsq ( const catacurses::window w,
const tripoint p,
const drawsq_params params 
) const

Draw the map tile at the given coordinate.

Called by map::draw().

Parameters
wThe window we are drawing in
pThe tile on this map to draw.
paramsDraw parameters.

Definition at line 5968 of file map.cpp.

5970{
5971 // If we are in tiles mode, the only thing we want to potentially draw is a highlight
5972 if( is_draw_tiles_mode() ) {
5973 if( params.highlight() ) {
5974 g->draw_highlight( p );
5975 }
5976 return;
5977 }
5978
5979 if( !inbounds( p ) ) {
5980 return;
5981 }
5982
5983 const tripoint view_center = params.center();
5984 const int k = p.x + getmaxx( w ) / 2 - view_center.x;
5985 const int j = p.y + getmaxy( w ) / 2 - view_center.y;
5986 wmove( w, point( k, j ) );
5987
5988 const maptile tile = maptile_at( p );
5989 if( draw_maptile( w, p, tile, params ) ) {
5990 return;
5991 }
5992
5993 tripoint below( p.xy(), p.z - 1 );
5994 const maptile tile_below = maptile_at( below );
5995 draw_from_above( w, below, tile_below, params );
5996}
maptile maptile_at(const tripoint &p) const
Definition: map.cpp:261
constexpr drawsq_params & center(const tripoint &p)
Set view center.
Definition: map.h:283

References drawsq_params::center(), draw_from_above(), draw_maptile(), g, catacurses::getmaxx(), catacurses::getmaxy(), drawsq_params::highlight(), inbounds(), is_draw_tiles_mode(), maptile_at(), catacurses::wmove(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by anonymous_namespace{animation.cpp}::draw_line_curses(), game::draw_look_around_cursor(), editmap::draw_main_ui_overlay(), target_ui::draw_terrain_overlay(), game::pickup(), and editmap::uber_draw_ter().

◆ drop_everything()

void map::drop_everything ( const tripoint p)

Handles map objects of given type (not creatures) falling down.

Returns true if anything changed.

Definition at line 2127 of file map.cpp.

2128{
2129 //Do a suspension check so that there won't be a floor there for the rest of this check.
2130 if( has_flag( "SUSPENDED", p ) ) {
2132 }
2133 if( has_floor( p ) ) {
2134 return;
2135 }
2136
2137 drop_furniture( p );
2138 drop_items( p );
2139 drop_vehicle( p );
2140 drop_fields( p );
2141}
void drop_furniture(const tripoint &p)
Definition: map.cpp:2143
void drop_items(const tripoint &p)
Definition: map.cpp:2285
void drop_vehicle(const tripoint &p)
Definition: map.cpp:2315
void collapse_invalid_suspension(const tripoint &point)
Triggers a recursive collapse of suspended tiles based on their support validity.
Definition: map.cpp:3015
void drop_fields(const tripoint &p)
Definition: map.cpp:2325
bool has_floor(const tripoint &p) const
Definition: map.cpp:2072

References collapse_invalid_suspension(), drop_fields(), drop_furniture(), drop_items(), drop_vehicle(), has_flag(), and has_floor().

Referenced by process_falling().

◆ drop_fields()

void map::drop_fields ( const tripoint p)

Definition at line 2325 of file map.cpp.

2326{
2327 field &fld = field_at( p );
2328 if( fld.field_count() == 0 ) {
2329 return;
2330 }
2331
2332 std::list<field_type_id> dropped;
2333 const tripoint below = p + tripoint_below;
2334 for( const auto &iter : fld ) {
2335 const field_entry &entry = iter.second;
2336 // For now only drop cosmetic fields, which don't warrant per-turn check
2337 // Active fields "drop themselves"
2338 if( entry.decays_on_actualize() ) {
2339 add_field( below, entry.get_field_type(), entry.get_field_intensity(), entry.get_field_age() );
2340 dropped.push_back( entry.get_field_type() );
2341 }
2342 }
2343
2344 for( const auto &entry : dropped ) {
2345 fld.remove_field( entry );
2346 }
2347}
bool decays_on_actualize() const
Definition: field.h:105

References add_field(), field_entry::decays_on_actualize(), field_at(), field::field_count(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field::remove_field(), and tripoint_below.

Referenced by drop_everything().

◆ drop_furniture()

void map::drop_furniture ( const tripoint p)

Definition at line 2143 of file map.cpp.

2144{
2145 const furn_id frn = furn( p );
2146 if( frn == f_null ) {
2147 return;
2148 }
2149
2150 enum support_state {
2151 SS_NO_SUPPORT = 0,
2152 SS_BAD_SUPPORT, // TODO: Implement bad, shaky support
2153 SS_GOOD_SUPPORT,
2154 SS_FLOOR, // Like good support, but bash floor instead of tile below
2155 SS_CREATURE
2156 };
2157
2158 // Checks if the tile:
2159 // has floor (supports unconditionally)
2160 // has support below
2161 // has unsupporting furniture below (bad support, things should "slide" if possible)
2162 // has no support and thus allows things to fall through
2163 const auto check_tile = [this]( const tripoint & pt ) {
2164 if( has_floor( pt ) ) {
2165 return SS_FLOOR;
2166 }
2167
2168 tripoint below_dest( pt.xy(), pt.z - 1 );
2169 if( supports_above( below_dest ) ) {
2170 return SS_GOOD_SUPPORT;
2171 }
2172
2173 const furn_id frn_id = furn( below_dest );
2174 if( frn_id != f_null ) {
2175 const furn_t &frn = frn_id.obj();
2176 // Allow crushing tiny/nocollide furniture
2177 if( !frn.has_flag( "TINY" ) && !frn.has_flag( "NOCOLLIDE" ) ) {
2178 return SS_BAD_SUPPORT;
2179 }
2180 }
2181
2182 if( g->critter_at( below_dest ) != nullptr ) {
2183 // Smash a critter
2184 return SS_CREATURE;
2185 }
2186
2187 return SS_NO_SUPPORT;
2188 };
2189
2190 tripoint current( p.xy(), p.z + 1 );
2191 support_state last_state = SS_NO_SUPPORT;
2192 while( last_state == SS_NO_SUPPORT ) {
2193 current.z--;
2194 // Check current tile
2195 last_state = check_tile( current );
2196 }
2197
2198 if( current == p ) {
2199 // Nothing happened
2200 if( last_state != SS_FLOOR ) {
2201 support_dirty( current );
2202 }
2203
2204 return;
2205 }
2206
2207 furn_set( p, f_null );
2208 furn_set( current, frn );
2209
2210 // If it's sealed, we need to drop items with it
2211 const auto &frn_obj = frn.obj();
2212 if( frn_obj.has_flag( TFLAG_SEALED ) && has_items( p ) ) {
2213 auto old_items = i_at( p );
2214 auto new_items = i_at( current );
2215 for( const auto &it : old_items ) {
2216 new_items.insert( it );
2217 }
2218
2219 i_clear( p );
2220 }
2221
2222 // Approximate weight/"bulkiness" based on strength to drag
2223 int weight;
2224 if( frn_obj.has_flag( "TINY" ) || frn_obj.has_flag( "NOCOLLIDE" ) ) {
2225 weight = 5;
2226 } else {
2227 weight = frn_obj.is_movable() ? frn_obj.move_str_req : 20;
2228 }
2229
2230 if( frn_obj.has_flag( "ROUGH" ) || frn_obj.has_flag( "SHARP" ) ) {
2231 weight += 5;
2232 }
2233
2234 // TODO: Balance this.
2235 int dmg = weight * ( p.z - current.z );
2236
2237 if( last_state == SS_FLOOR ) {
2238 // Bash the same tile twice - once for furniture, once for the floor
2239 bash( current, dmg, false, false, true );
2240 bash( current, dmg, false, false, true );
2241 } else if( last_state == SS_BAD_SUPPORT || last_state == SS_GOOD_SUPPORT ) {
2242 bash( current, dmg, false, false, false );
2243 tripoint below( current.xy(), current.z - 1 );
2244 bash( below, dmg, false, false, false );
2245 } else if( last_state == SS_CREATURE ) {
2246 const std::string &furn_name = frn_obj.name();
2247 bash( current, dmg, false, false, false );
2248 tripoint below( current.xy(), current.z - 1 );
2249 Creature *critter = g->critter_at( below );
2250 if( critter == nullptr ) {
2251 debugmsg( "drop_furniture couldn't find creature at %d,%d,%d",
2252 below.x, below.y, below.z );
2253 return;
2254 }
2255
2256 critter->add_msg_player_or_npc( m_bad, _( "Falling %s hits you!" ),
2257 _( "Falling %s hits <npcname>" ),
2258 furn_name );
2259 // TODO: A chance to dodge/uncanny dodge
2260 player *pl = dynamic_cast<player *>( critter );
2261 monster *mon = dynamic_cast<monster *>( critter );
2262 if( pl != nullptr ) {
2263 pl->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2264 0.5f ) );
2265 pl->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2266 0.5f ) );
2267 pl->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2268 0.4f ) );
2269 pl->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2270 0.4f ) );
2271 pl->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2272 0.4f ) );
2273 pl->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2274 0.4f ) );
2275 } else if( mon != nullptr ) {
2276 // TODO: Monster's armor and size - don't crush hulks with chairs
2277 mon->apply_damage( nullptr, bodypart_id( "torso" ), rng( dmg, dmg * 2 ) );
2278 }
2279 }
2280
2281 // Re-queue for another check, in case bash destroyed something
2282 support_dirty( current );
2283}
bool supports_above(const tripoint &p) const
Does this tile support vehicles and furniture above it.
Definition: map.cpp:2102
void apply_damage(Creature *source, bodypart_id bp, int dam, bool bypass_med=false) override
Definition: monster.cpp:1691

References _, Creature::add_msg_player_or_npc(), monster::apply_damage(), bash(), Character::deal_damage(), debugmsg, DT_BASH, f_null, furn(), furn_set(), g, map_data_common_t::has_flag(), has_floor(), has_items(), i_at(), i_clear(), m_bad, int_id< T >::obj(), rng(), support_dirty(), supports_above(), TFLAG_SEALED, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by drop_everything().

◆ drop_items()

void map::drop_items ( const tripoint p)

Definition at line 2285 of file map.cpp.

2286{
2287 if( !has_items( p ) ) {
2288 return;
2289 }
2290
2291 auto items = i_at( p );
2292 // TODO: Make items check the volume tile below can accept
2293 // rather than disappearing if it would be overloaded
2294
2295 tripoint below( p );
2296 while( !has_floor( below ) ) {
2297 below.z--;
2298 }
2299
2300 if( below == p ) {
2301 return;
2302 }
2303
2304 for( const auto &i : items ) {
2305 // TODO: Bash the item up before adding it
2306 // TODO: Bash the creature, terrain, furniture and vehicles on the tile
2307 add_item_or_charges( below, i );
2308 }
2309
2310 // Just to make a sound for now
2311 bash( below, 1 );
2312 i_clear( p );
2313}

References add_item_or_charges(), bash(), has_floor(), has_items(), i_at(), i_clear(), and tripoint::z.

Referenced by drop_everything().

◆ drop_vehicle()

void map::drop_vehicle ( const tripoint p)

Definition at line 2315 of file map.cpp.

2316{
2317 const optional_vpart_position vp = veh_at( p );
2318 if( !vp ) {
2319 return;
2320 }
2321
2322 vp->vehicle().is_falling = true;
2323}

References veh_at().

Referenced by drop_everything().

◆ emit_field()

void map::emit_field ( const tripoint pos,
const emit_id src,
float  mul = 1.0f 
)

Runs one cycle of emission src which may result in propagation of fields.

Parameters
posLocation of emission
srcId of object producing the emission
mulMultiplies the chance and possibly qty (if chance*mul > 100) of the emission

Definition at line 1928 of file map_field.cpp.

1929{
1930 if( !src.is_valid() ) {
1931 return;
1932 }
1933
1934 const float chance = src->chance() * mul;
1935 if( src.is_valid() && x_in_y( chance, 100 ) ) {
1936 const int qty = chance > 100.0f ? roll_remainder( src->qty() * chance / 100.0f ) : src->qty();
1937 propagate_field( pos, src->field(), qty, src->intensity() );
1938 }
1939}
int intensity() const
Intensity of output fields, range [1..maximum_intensity].
Definition: emit.h:34
int qty() const
Units of field to generate per turn subject to chance.
Definition: emit.h:39
int chance() const
Chance to emit each turn, range [1..100].
Definition: emit.h:44
field_type_id field() const
Type of field to emit.
Definition: emit.h:29
void propagate_field(const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
Definition: map_field.cpp:1941
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:70
int roll_remainder(double value)
Definition: rng.cpp:96

References emit::chance(), emit::field(), emit::intensity(), string_id< T >::is_valid(), propagate_field(), emit::qty(), roll_remainder(), and x_in_y().

Referenced by enchantment::activate_passive(), and game::do_turn().

◆ examine()

void map::examine ( Character p,
const tripoint pos 
)

Calls the examine function of furniture or terrain at given tile, for given character.

Examines the tile pos, with character as the "examinator" Casts Character to player because player/NPC split isn't done yet.

Will only examine terrain if furniture had iexamine::none as the examine function.

Definition at line 1685 of file map.cpp.

1686{
1687 const auto furn_here = furn( pos ).obj();
1688 if( furn_here.examine != iexamine::none ) {
1689 furn_here.examine( dynamic_cast<player &>( p ), pos );
1690 } else {
1691 ter( pos ).obj().examine( dynamic_cast<player &>( p ), pos );
1692 }
1693}
void none(player &p, const tripoint &examp)
Nothing player can interact with here.
Definition: iexamine.cpp:253
iexamine_function examine
Definition: mapdata.h:404

References map_data_common_t::examine, furn(), iexamine::none(), int_id< T >::obj(), wrapped_vehicle::pos, and ter().

Referenced by water_from().

◆ features() [1/2]

std::string map::features ( const tripoint p)

Definition at line 1779 of file map.cpp.

1780{
1781 std::string result;
1782 const auto add = [&]( const std::string & text ) {
1783 if( !result.empty() ) {
1784 result += " ";
1785 }
1786 result += text;
1787 };
1788 const auto add_if = [&]( const bool cond, const std::string & text ) {
1789 if( cond ) {
1790 add( text );
1791 }
1792 };
1793 // This is used in an info window that is 46 characters wide, and is expected
1794 // to take up one line. So, make sure it does that.
1795 // FIXME: can't control length of localized text.
1796 add_if( is_bashable( p ), _( "Smashable." ) );
1797 add_if( has_flag( "DIGGABLE", p ), _( "Diggable." ) );
1798 add_if( has_flag( "PLOWABLE", p ), _( "Plowable." ) );
1799 add_if( has_flag( "ROUGH", p ), _( "Rough." ) );
1800 add_if( has_flag( "UNSTABLE", p ), _( "Unstable." ) );
1801 add_if( has_flag( "SHARP", p ), _( "Sharp." ) );
1802 add_if( has_flag( "FLAT", p ), _( "Flat." ) );
1803 add_if( has_flag( "EASY_DECONSTRUCT", p ), _( "Simple." ) );
1804 add_if( has_flag( "MOUNTABLE", p ), _( "Mountable." ) );
1805 return result;
1806}
bool is_bashable(const tripoint &p, bool allow_floor=false) const
Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.
Definition: map.cpp:2507
type add(type dir1, type dir2)
Returns a sum of two numbers.
Definition: overmap.cpp:4195

References _, om_direction::add(), has_flag(), and is_bashable().

Referenced by features(), and game::print_terrain_info().

◆ features() [2/2]

std::string map::features ( point  p)
inline

Definition at line 899 of file map.h.

899 {
900 return features( tripoint( p, abs_sub.z ) );
901 }
std::string features(const tripoint &p)
Definition: map.cpp:1779

References abs_sub, features(), and tripoint::z.

◆ field_at() [1/2]

field & map::field_at ( const tripoint p)

Gets fields that are here.

Both for querying and edition.

Definition at line 5436 of file map.cpp.

5437{
5438 if( !inbounds( p ) ) {
5439 nulfield = field();
5440 return nulfield;
5441 }
5442
5443 point l;
5444 submap *const current_submap = get_submap_at( p, l );
5445
5446 return current_submap->get_field( l );
5447}
static field nulfield
Definition: map.cpp:143
@ field
Consumes field to recharge.

References field, submap::get_field(), get_submap_at(), inbounds(), and nulfield.

◆ field_at() [2/2]

const field & map::field_at ( const tripoint p) const

Get the fields that are here.

This is for querying and looking at it only, one can not change the fields.

Parameters
pThe local map coordinates, if out of bounds, returns an empty field.

Definition at line 5420 of file map.cpp.

5421{
5422 if( !inbounds( p ) ) {
5423 nulfield = field();
5424 return nulfield;
5425 }
5426
5427 point l;
5428 submap *const current_submap = get_submap_at( p, l );
5429
5430 return current_submap->get_field( l );
5431}

References field, submap::get_field(), get_submap_at(), inbounds(), and nulfield.

Referenced by dangerous_field_at(), decay_cosmetic_fields(), editmap::draw_main_ui_overlay(), drop_fields(), game::get_dangerous_tile(), get_field(), get_field_age(), get_field_intensity(), mop_spills(), game::print_fields_info(), process_fields_in_submap(), and Character::symbol_color().

◆ fill_funnels()

void map::fill_funnels ( const tripoint p,
const time_point since 
)
protected

Try to fill funnel based items here.

Simulates rain from since till now.

Parameters
pThe location in this map where to fill funnels.

Definition at line 7269 of file map.cpp.

7270{
7271 const auto &tr = tr_at( p );
7272 if( !tr.is_funnel() ) {
7273 return;
7274 }
7275 // Note: the inside/outside cache might not be correct at this time
7277 return;
7278 }
7279 auto items = i_at( p );
7280 units::volume maxvolume = 0_ml;
7281 auto biggest_container = items.end();
7282 for( auto candidate = items.begin(); candidate != items.end(); ++candidate ) {
7283 if( candidate->is_funnel_container( maxvolume ) ) {
7284 biggest_container = candidate;
7285 }
7286 }
7287 if( biggest_container != items.end() ) {
7288 retroactively_fill_from_funnel( *biggest_container, tr, since, calendar::turn, getabs( p ) );
7289 }
7290}
void retroactively_fill_from_funnel(item &it, const trap &tr, const time_point &start, const time_point &end, const tripoint &pos)
Determine what a funnel has filled out of game, using funnelcontainer.bday as a starting point.
Definition: weather.cpp:184

References getabs(), has_flag_ter_or_furn(), i_at(), retroactively_fill_from_funnel(), TFLAG_INDOORS, tr_at(), and calendar::turn.

Referenced by actualize().

◆ find_clear_path()

std::vector< tripoint > map::find_clear_path ( const tripoint source,
const tripoint destination 
) const

Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one.

returns the line found, which may be the straight line, but blocked.

Definition at line 6402 of file map.cpp.

6404{
6405 // TODO: Push this junk down into the Bresenham method, it's already doing it.
6406 const point d( destination.xy() - source.xy() );
6407 const point a( std::abs( d.x ) * 2, std::abs( d.y ) * 2 );
6408 const int dominant = std::max( a.x, a.y );
6409 const int minor = std::min( a.x, a.y );
6410 // This seems to be the method for finding the ideal start value for the error value.
6411 const int ideal_start_offset = minor - dominant / 2;
6412 const int start_sign = ( ideal_start_offset > 0 ) - ( ideal_start_offset < 0 );
6413 // Not totally sure of the derivation.
6414 const int max_start_offset = std::abs( ideal_start_offset ) * 2 + 1;
6415 for( int horizontal_offset = -1; horizontal_offset <= max_start_offset; ++horizontal_offset ) {
6416 int candidate_offset = horizontal_offset * start_sign;
6417 if( sees( source, destination, rl_dist( source, destination ), candidate_offset ) ) {
6418 return line_to( source, destination, candidate_offset, 0 );
6419 }
6420 }
6421 // If we couldn't find a clear LoS, just return the ideal one.
6422 return line_to( source, destination, ideal_start_offset, 0 );
6423}
bool sees(const tripoint &F, const tripoint &T, int range) const
Returns whether F sees T with a view range of range.
Definition: map.cpp:6270

References a, line_to(), minor, rl_dist(), sees(), point::x, tripoint::xy(), and point::y.

◆ find_furnitures_or_vparts_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_or_vparts_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures or vehicle parts with matching flag in the specified radius

Definition at line 8848 of file map.cpp.

8850{
8851 std::list<tripoint> locs;
8852 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8853 // workaround for ramp bridges
8854 int dz = 0;
8855 if( has_flag( TFLAG_RAMP_UP, loc ) ) {
8856 dz = 1;
8857 } else if( has_flag( TFLAG_RAMP_DOWN, loc ) ) {
8858 dz = -1;
8859 }
8860
8861 if( dz == 0 ) {
8862 if( has_flag_furn_or_vpart( flag, loc ) ) {
8863 locs.push_back( loc );
8864 }
8865 } else {
8866 const tripoint newloc( loc + tripoint( 0, 0, dz ) );
8867 if( has_flag_furn_or_vpart( flag, newloc ) ) {
8868 locs.push_back( newloc );
8869 }
8870 }
8871 }
8872
8873 return locs;
8874}
bool has_flag_furn_or_vpart(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2439

References center, has_flag(), has_flag_furn_or_vpart(), points_in_radius(), TFLAG_RAMP_DOWN, and TFLAG_RAMP_UP.

◆ find_furnitures_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures with matching flag in the specified radius

Definition at line 8834 of file map.cpp.

8838{
8839 std::list<tripoint> furn_locs;
8840 for( const auto &furn_loc : points_in_radius( center, radius, radiusz ) ) {
8841 if( has_flag_furn( flag, furn_loc ) ) {
8842 furn_locs.push_back( furn_loc );
8843 }
8844 }
8845 return furn_locs;
8846}

References center, has_flag_furn(), and points_in_radius().

◆ flammable_items_at()

bool map::flammable_items_at ( const tripoint p,
int  threshold = 0 
)

Checks if there are any flammable items on the tile.

Parameters
ptile to check
thresholdFuel threshold (lower means worse fuels are accepted).

Definition at line 2688 of file map.cpp.

2689{
2690 if( !has_items( p ) ||
2692 // Sealed containers don't allow fire, so shouldn't allow setting the fire either
2693 return false;
2694 }
2695
2696 for( const auto &i : i_at( p ) ) {
2697 if( i.flammable( threshold ) ) {
2698 return true;
2699 }
2700 }
2701
2702 return false;
2703}
@ TFLAG_ALLOW_FIELD_EFFECT
Definition: mapdata.h:287

References has_flag(), has_items(), i_at(), TFLAG_ALLOW_FIELD_EFFECT, and TFLAG_SEALED.

Referenced by MapExtras::burned_ground_parser(), is_flammable(), and process_fields_in_submap().

◆ floor_between()

bool map::floor_between ( const tripoint first,
const tripoint second 
) const

Checks if there's a floor between the two tiles.

They must be at most 1 tile away from each other in any dimension. If they're not at the same xy coord there must be floor on both of the relevant tiles

Definition at line 2085 of file map.cpp.

2086{
2087 int diff = std::abs( first.z - second.z );
2088 if( diff == 0 ) { //There's never a floor between two tiles on the same level
2089 return false;
2090 }
2091 if( diff != 1 ) {
2092 debugmsg( "map::floor_between should only be called on tiles that are exactly 1 z level apart" );
2093 return true;
2094 }
2095 int upper = std::max( first.z, second.z );
2096 if( first.xy() == second.xy() ) {
2097 return has_floor( tripoint( first.xy(), upper ) );
2098 }
2099 return has_floor( tripoint( first.xy(), upper ) ) && has_floor( tripoint( second.xy(), upper ) );
2100}

References debugmsg, has_floor(), second, tripoint::xy(), and tripoint::z.

◆ free_volume()

units::volume map::free_volume ( const tripoint p)

Definition at line 4350 of file map.cpp.

4351{
4352 return i_at( p ).free_volume();
4353}
units::volume free_volume() const
Definition: item_stack.cpp:141

References item_stack::free_volume(), and i_at().

Referenced by add_item_or_charges(), and advanced_inv_area::free_volume().

◆ function_over()

template<typename Functor >
void map::function_over ( const tripoint start,
const tripoint end,
Functor  fun 
) const
private

Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time.

gp in the functor is Grid (like get_submap_at_grid) coordinate of the submap, Will silently clip the area to map bounds.

Parameters
startStarting point for function
endEnd point for function
funFunction to run

Definition at line 8648 of file map.cpp.

8649{
8650 // start and end are just two points, end can be "before" start
8651 // Also clip the area to map area
8652 const tripoint min( std::max( std::min( start.x, end.x ), 0 ), std::max( std::min( start.y, end.y ),
8653 0 ), std::max( std::min( start.z, end.z ), -OVERMAP_DEPTH ) );
8654 const tripoint max( std::min( std::max( start.x, end.x ), SEEX * my_MAPSIZE - 1 ),
8655 std::min( std::max( start.y, end.y ), SEEY * my_MAPSIZE - 1 ), std::min( std::max( start.z, end.z ),
8656 OVERMAP_HEIGHT ) );
8657
8658 // Submaps that contain the bounding points
8659 const point min_sm( min.x / SEEX, min.y / SEEY );
8660 const point max_sm( max.x / SEEX, max.y / SEEY );
8661 // Z outermost, because submaps are flat
8662 tripoint gp;
8663 int &z = gp.z;
8664 int &smx = gp.x;
8665 int &smy = gp.y;
8666 for( z = min.z; z <= max.z; z++ ) {
8667 for( smx = min_sm.x; smx <= max_sm.x; smx++ ) {
8668 for( smy = min_sm.y; smy <= max_sm.y; smy++ ) {
8669 submap const *cur_submap = get_submap_at_grid( { smx, smy, z } );
8670 // Bounds on the submap coordinates
8671 const point sm_min( smx > min_sm.x ? 0 : min.x % SEEX, smy > min_sm.y ? 0 : min.y % SEEY );
8672 const point sm_max( smx < max_sm.x ? SEEX - 1 : max.x % SEEX,
8673 smy < max_sm.y ? SEEY - 1 : max.y % SEEY );
8674
8675 point lp;
8676 int &sx = lp.x;
8677 int &sy = lp.y;
8678 for( sx = sm_min.x; sx <= sm_max.x; ++sx ) {
8679 for( sy = sm_min.y; sy <= sm_max.y; ++sy ) {
8680 const iteration_state rval = fun( gp, cur_submap, lp );
8681 if( rval != ITER_CONTINUE ) {
8682 switch( rval ) {
8683 case ITER_SKIP_ZLEVEL:
8684 smx = my_MAPSIZE + 1;
8685 smy = my_MAPSIZE + 1;
8686 // Fall through
8687 case ITER_SKIP_SUBMAP:
8688 sx = SEEX;
8689 sy = SEEY;
8690 break;
8691 default:
8692 return;
8693 }
8694 }
8695 }
8696 }
8697 }
8698 }
8699 }
8700}
iteration_state
Enum used by functors in function_over to control execution.
Definition: map.h:1933

References get_submap_at_grid(), ITER_CONTINUE, ITER_SKIP_SUBMAP, ITER_SKIP_ZLEVEL, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, sx, sy, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by scent_blockers().

◆ furn() [1/2]

furn_id map::furn ( const tripoint p) const

Definition at line 1413 of file map.cpp.

1414{
1415 if( !inbounds( p ) ) {
1416 return f_null;
1417 }
1418
1419 point l;
1420 submap *const current_submap = get_submap_at( p, l );
1421
1422 return current_submap->get_furn( l );
1423}
furn_id get_furn(point p) const
Definition: submap.h:86

References f_null, submap::get_furn(), get_submap_at(), and inbounds().

Referenced by actualize(), ter_furn_transform::add_all_messages(), bash_furn_success(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), board_up(), MapExtras::burned_ground_parser(), can_move_furniture(), close_door(), doors::close_door(), coverage(), create_anomaly(), MapExtras::dead_vegetation_parser(), destroy_furn(), game::do_turn(), draw_lab(), editmap::draw_main_ui_overlay(), drop_furniture(), examine(), game::examine(), game::extended_description(), farm_action(), feature< furn_id >(), talk_function::field_harvest(), find_potential_computer_point(), inventory::form_from_map(), furn(), furn_is_supported(), furnname(), get_changed_ids_from_update(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_furn_transforms_into(), get_harvest(), get_harvest_names(), get_keg_capacity(), game::grabbed_furn_move(), grow_plant(), has_adjacent_furniture_with(), has_flag_furn(), has_furn(), is_bashable(), is_bashable_furn(), talk_function::loot_building(), map_stack::max_volume(), avatar_action::move(), move_cost(), obstacle_coverage(), om_harvest_furn(), open_door(), Character::place_corpse(), game::place_player(), mission_start::place_priest_diary(), rad_scorch(), resolve_regional_terrain_and_furniture(), fungal_effects::spread_fungus_one_tile(), ter_furn_transform::transform(), use_charges(), iexamine::use_furn_fake_item(), game::walk_move(), and water_from().

◆ furn() [2/2]

furn_id map::furn ( point  p) const
inline

Definition at line 793 of file map.h.

793 {
794 return furn( tripoint( p, abs_sub.z ) );
795 }

References abs_sub, furn(), and tripoint::z.

◆ furn_set() [1/2]

void map::furn_set ( const tripoint p,
const furn_id new_furniture,
cata::poly_serialized< active_tile_data new_active = nullptr 
)

Sets the furniture at given position.

Parameters
pPosition within the map
new_furnitureId of new furniture
new_activeOverride default active tile of new furniture

Definition at line 1425 of file map.cpp.

1427{
1428 if( !inbounds( p ) ) {
1429 return;
1430 }
1431
1432 point l;
1433 submap *const current_submap = get_submap_at( p, l );
1434 const furn_id old_id = current_submap->get_furn( l );
1435 if( old_id == new_furniture ) {
1436 // Nothing changed
1437 return;
1438 }
1439
1440 current_submap->set_furn( l, new_furniture );
1441
1442 // Set the dirty flags
1443 const furn_t &old_t = old_id.obj();
1444 const furn_t &new_t = new_furniture.obj();
1445
1446 // If player has grabbed this furniture and it's no longer grabbable, release the grab.
1447 if( g->u.get_grab_type() == OBJECT_FURNITURE && g->u.grab_point == p && !new_t.is_movable() ) {
1448 add_msg( _( "The %s you were grabbing is destroyed!" ), old_t.name() );
1449 g->u.grab( OBJECT_NONE );
1450 }
1451 // If a creature was crushed under a rubble -> free it
1452 if( old_id == f_rubble && new_furniture == f_null ) {
1453 Creature *c = g->critter_at( p );
1454 if( c ) {
1455 c->remove_effect( effect_crushed );
1456 }
1457 }
1458 if( new_t.has_flag( "EMITTER" ) ) {
1459 field_furn_locs.push_back( p );
1460 }
1461 if( old_t.transparent != new_t.transparent ) {
1464 }
1465
1466 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1468 }
1469
1470 if( old_t.has_flag( TFLAG_NO_FLOOR ) != new_t.has_flag( TFLAG_NO_FLOOR ) ) {
1473 }
1474
1475 if( old_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) != new_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) ) {
1476 set_floor_cache_dirty( p.z + 1 );
1477 }
1478
1480
1482
1483 // TODO: Limit to changes that affect move cost, traps and stairs
1485
1486 // Make sure the furniture falls if it needs to
1487 support_dirty( p );
1488 tripoint above( p.xy(), p.z + 1 );
1489 // Make sure that if we supported something and no longer do so, it falls down
1490 support_dirty( above );
1491
1492 if( old_t.active ) {
1493 current_submap->active_furniture.erase( point_sm_ms( l ) );
1494 // TODO: Only for g->m? Observer pattern?
1496 }
1497 if( new_t.active || new_active ) {
1499 if( new_active ) {
1500 atd = new_active;
1501 } else {
1502 atd = new_t.active->clone();
1503 atd->set_last_updated( calendar::turn );
1504 }
1505 current_submap->active_furniture[point_sm_ms( l )] = atd;
1507 }
1508}
Copyable unique_ptr that writes and reads objects of derived types.
void on_changed(const tripoint_abs_ms &p)
Updates grid at given global map square coordinate.
void set_floor_cache_dirty(const int zlev)
Definition: map.cpp:236
void set_memory_seen_cache_dirty(const tripoint &p)
Definition: map.cpp:8982
std::map< point_sm_ms, cata::poly_serialized< active_tile_data > > active_furniture
Definition: submap.h:221
void set_furn(point p, furn_id furn)
Definition: submap.h:90
coords::coord_point< point, coords::origin::submap, coords::ms > point_sm_ms
Definition: coordinates.h:473
coords::coord_point< tripoint, coords::origin::abs, coords::ms > tripoint_abs_ms
Definition: coordinates.h:486
distribution_grid_tracker & get_distribution_grid_tracker()
Returns distribution grid tracker that is a part of the global game *g.
Definition: game.cpp:12117
@ OBJECT_NONE
Definition: enums.h:187
@ OBJECT_FURNITURE
Definition: enums.h:197
bool is_movable() const
Definition: mapdata.cpp:1524
cata::poly_serialized< active_tile_data > active
Definition: mapdata.h:527
std::string name() const
Definition: mapdata.cpp:514

References _, furn_t::active, submap::active_furniture, add_msg(), c, effect_crushed, f_null, f_rubble, field_furn_locs, g, get_distribution_grid_tracker(), submap::get_furn(), get_submap_at(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), furn_t::is_movable(), map_data_common_t::name(), int_id< T >::obj(), OBJECT_FURNITURE, OBJECT_NONE, distribution_grid_tracker::on_changed(), set_floor_cache_dirty(), submap::set_furn(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, map_data_common_t::transparent, calendar::turn, tripoint::xy(), and tripoint::z.

Referenced by grid_furn_transform_queue::apply(), jmapgen_sign::apply(), jmapgen_vending_machine::apply(), jmapgen_toilet::apply(), jmapgen_gaspump::apply(), jmapgen_furniture::apply(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_sealed_item::apply(), jmapgen_setmap::apply(), bash_furn_success(), board_up(), MapExtras::burned_ground_parser(), close_door(), collapse_at(), collapse_invalid_suspension(), activity_handlers::cracking_finish(), create_anomaly(), MapExtras::dead_vegetation_parser(), draw_circle_furn(), draw_lab(), draw_line_furn(), draw_rough_circle_furn(), draw_square_furn(), drop_furniture(), farm_action(), talk_function::field_harvest(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), furn_set(), game::grabbed_furn_move(), grow_plant(), iexamine::harvest_furn(), iexamine::harvest_furn_nectar(), talk_function::loot_building(), make_rubble(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_lake_shore(), mapgen_tutorial(), MapExtras::mx_burned_ground(), MapExtras::mx_clay_deposit(), MapExtras::mx_grave(), MapExtras::mx_house_spider(), MapExtras::mx_minefield(), MapExtras::mx_pond(), MapExtras::mx_roadworks(), MapExtras::mx_spider(), MapExtras::mx_supplydrop(), om_harvest_furn(), open_door(), iexamine::open_safe(), place_toilet(), place_vending(), process_fields_in_submap(), rad_scorch(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), iexamine::safe(), science_room(), set(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_furn_transform::transform(), and game::vertical_move().

◆ furn_set() [2/2]

void map::furn_set ( point  p,
const furn_id new_furniture 
)
inline

Definition at line 805 of file map.h.

805 {
806 furn_set( tripoint( p, abs_sub.z ), new_furniture );
807 }

References abs_sub, furn_set(), and tripoint::z.

◆ furnname() [1/2]

std::string map::furnname ( const tripoint p)

Definition at line 1534 of file map.cpp.

1535{
1536 const furn_t &f = furn( p ).obj();
1537 if( f.has_flag( "PLANT" ) ) {
1538 // Can't use item_stack::only_item() since there might be fertilizer
1539 map_stack items = i_at( p );
1540 const map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
1541 return it.is_seed();
1542 } );
1543 if( seed == items.end() ) {
1544 debugmsg( "Missing seed for plant at (%d, %d, %d)", p.x, p.y, p.z );
1545 return "null";
1546 }
1547 const std::string &plant = seed->get_plant_name();
1548 return string_format( "%s (%s)", f.name(), plant );
1549 } else {
1550 return f.name();
1551 }
1552}
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
Definition: map.h:105
int seed(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:5972

References item_stack::begin(), debugmsg, item_stack::end(), furn(), map_data_common_t::has_flag(), i_at(), map_data_common_t::name(), int_id< T >::obj(), plant, iuse::seed(), string_format(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by furnname(), name(), and game::place_player().

◆ furnname() [2/2]

std::string map::furnname ( point  p)
inline

Definition at line 809 of file map.h.

809 {
810 return furnname( tripoint( p, abs_sub.z ) );
811 }
std::string furnname(const tripoint &p)
Definition: map.cpp:1534

References abs_sub, furnname(), and tripoint::z.

◆ gas_can_spread_to()

bool map::gas_can_spread_to ( field_entry cur,
const tripoint src,
const tripoint dst 
)
private

Definition at line 212 of file map_field.cpp.

213{
214 maptile dst_tile = maptile_at( dst );
215 const field_entry *tmpfld = dst_tile.get_field().find_field( cur.get_field_type() );
216 // Candidates are existing weaker fields or navigable/flagged tiles with no field.
217 if( tmpfld == nullptr || tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
218 const ter_t &ter = dst_tile.get_ter_t();
219 const furn_t &frn = dst_tile.get_furn_t();
220 return !obstructed_by_vehicle_rotation( src, dst ) &&
221 ( ter_furn_movecost( ter, frn ) > 0 || ter_furn_has_flag( ter, frn, TFLAG_PERMEABLE ) );
222 }
223 return false;
224}
bool ter_furn_has_flag(const ter_t &ter, const furn_t &furn, const ter_bitflags flag)
Definition: map_field.cpp:162
static int ter_furn_movecost(const ter_t &ter, const furn_t &furn)
Definition: map_field.cpp:167
@ TFLAG_PERMEABLE
Definition: mapdata.h:305
const ter_t & get_ter_t() const
Definition: submap.h:271
const field & get_field() const
Definition: submap.h:275
const furn_t & get_furn_t() const
Definition: submap.h:268

References field::find_field(), maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_ter_t(), maptile_at(), obstructed_by_vehicle_rotation(), ter(), ter_furn_has_flag(), ter_furn_movecost(), and TFLAG_PERMEABLE.

Referenced by spread_gas().

◆ gas_spread_to()

void map::gas_spread_to ( field_entry cur,
maptile dst,
const tripoint p 
)
private

Definition at line 226 of file map_field.cpp.

227{
228 const field_type_id current_type = cur.get_field_type();
229 const time_duration current_age = cur.get_field_age();
230 const int current_intensity = cur.get_field_intensity();
231 field_entry *f = dst.find_field( current_type );
232 // Nearby gas grows thicker, and ages are shared.
233 const time_duration age_fraction = current_age / current_intensity;
234 if( f != nullptr ) {
236 cur.set_field_intensity( current_intensity - 1 );
237 f->set_field_age( f->get_field_age() + age_fraction );
238 cur.set_field_age( current_age - age_fraction );
239 // Or, just create a new field.
240 } else if( add_field( p, current_type, 1, 0_turns ) ) {
241 f = dst.find_field( current_type );
242 if( f != nullptr ) {
243 f->set_field_age( age_fraction );
244 } else {
245 debugmsg( "While spreading the gas, field was added but doesn't exist." );
246 }
247 cur.set_field_intensity( current_intensity - 1 );
248 cur.set_field_age( current_age - age_fraction );
249 }
250}
int set_field_intensity(int new_intensity)
Definition: field.cpp:126
field_entry * find_field(const field_type_id &field_to_find)
Definition: submap.h:279

References add_field(), debugmsg, maptile::find_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_entry::set_field_age(), and field_entry::set_field_intensity().

Referenced by spread_gas().

◆ generate()

void map::generate ( const tripoint p,
const time_point when 
)

Definition at line 109 of file mapgen.cpp.

110{
111 dbg( DL::Info ) << "map::generate( g[" << g.get() << "], p[" << p <<
112 "], when[" << to_string( when ) << "] )";
113
114 set_abs_sub( p );
115
116 // First we have to create new submaps and initialize them to 0 all over
117 // We create all the submaps, even if we're not a tinymap, so that map
118 // generation which overflows won't cause a crash. At the bottom of this
119 // function, we save the upper-left 4 submaps, and delete the rest.
120 // Mapgen is not z-level aware yet. Only actually initialize current z-level
121 // because other submaps won't be touched.
122 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
123 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
124 const size_t grid_pos = get_nonant( { gridx, gridy, p.z } );
125 if( getsubmap( grid_pos ) ) {
126 debugmsg( "Submap already exists at (%d, %d, %d)", gridx, gridy, p.z );
127 continue;
128 }
129 setsubmap( grid_pos, new submap() );
130 // TODO: memory leak if the code below throws before the submaps get stored/deleted!
131 }
132 }
133 // x, and y are submap coordinates, convert to overmap terrain coordinates
134 // TODO: fix point types
135 tripoint_abs_omt abs_omt( sm_to_omt_copy( p ) );
136 oter_id terrain_type = overmap_buffer.ter( abs_omt );
137
138 // This attempts to scale density of zombies inversely with distance from the nearest city.
139 // In other words, make city centers dense and perimeters sparse.
140 float density = 0.0;
141 for( int i = -MON_RADIUS; i <= MON_RADIUS; i++ ) {
142 for( int j = -MON_RADIUS; j <= MON_RADIUS; j++ ) {
143 density += overmap_buffer.ter( abs_omt + point( i, j ) )->get_mondensity();
144 }
145 }
146 density = density / 100;
147
148 mapgendata dat( abs_omt, *this, density, when, nullptr );
149 draw_map( dat );
150
151 // At some point, we should add region information so we can grab the appropriate extras
152 map_extras ex = region_settings_map["default"].region_extras[terrain_type->get_extras()];
153 if( ex.chance > 0 && one_in( ex.chance ) ) {
154 std::string *extra = ex.values.pick();
155 if( extra == nullptr ) {
156 debugmsg( "failed to pick extra for type %s", terrain_type->get_extras() );
157 } else {
158 MapExtras::apply_function( *( ex.values.pick() ), *this, abs_sub );
159 }
160 }
161
162 const auto &spawns = terrain_type->get_static_spawns();
163
164 float spawn_density = 1.0f;
165 if( MonsterGroupManager::is_animal( spawns.group ) ) {
166 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
167 } else {
168 spawn_density = get_option< float >( "SPAWN_DENSITY" );
169 }
170
171 // Apply a multiplier to the number of monsters for really high densities.
172 float odds_after_density = spawns.chance * spawn_density;
173 const float max_odds = 100 - ( 100 - spawns.chance ) / 2.0;
174 float density_multiplier = 1.0f;
175 if( odds_after_density > max_odds ) {
176 density_multiplier = 1.0f * odds_after_density / max_odds;
177 odds_after_density = max_odds;
178 }
179 const int spawn_count = roll_remainder( density_multiplier );
180
181 if( spawns.group && x_in_y( odds_after_density, 100 ) ) {
182 int pop = spawn_count * rng( spawns.population.min, spawns.population.max );
183 for( ; pop > 0; pop-- ) {
184 MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( spawns.group, &pop );
185 if( !spawn_details.name ) {
186 continue;
187 }
188 if( const std::optional<tripoint> pt =
189 random_point( *this, [this]( const tripoint & n ) {
190 return passable( n );
191 } ) ) {
192 add_spawn( spawn_details.name, spawn_details.pack_size, *pt );
193 }
194 }
195 }
196
199 *this,
200 sm_to_omt_copy( p ),
201 when
202 );
203
204 // Okay, we know who are neighbors are. Let's draw!
205 // And finally save used submaps and delete the rest.
206 for( int i = 0; i < my_MAPSIZE; i++ ) {
207 for( int j = 0; j < my_MAPSIZE; j++ ) {
208 dbg( DL::Info ) << "map::generate: submap (" << i << "," << j << ")";
209
210 const tripoint pos( i, j, p.z );
211 if( i <= 1 && j <= 1 ) {
212 saven( pos );
213 } else {
214 const size_t grid_pos = get_nonant( pos );
215 delete getsubmap( grid_pos );
216 setsubmap( grid_pos, nullptr );
217 }
218 }
219 }
220}
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
static DynamicDataLoader & get_instance()
Returns the single instance of this class.
Definition: init.cpp:120
static bool is_animal(const mongroup_id &group)
Definition: mongroup.cpp:401
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void saven(const tripoint &grid)
Definition: map.cpp:7078
void set_abs_sub(const tripoint &p)
Sets abs_sub, see there.
Definition: map.cpp:8428
void draw_map(mapgendata &dat)
Definition: mapgen.cpp:2922
submap * getsubmap(size_t grididx) const
Get the submap pointer with given index in grid, the index must be valid!
Definition: map.cpp:8438
void add_spawn(const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
Definition: mapgen.cpp:5416
bool passable(const tripoint &p) const
Definition: map.cpp:1865
Contains various information regarding the individual mapgen instance (generating a specific part of ...
Definition: mapgendata.h:36
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
point sm_to_omt_copy(point p)
static constexpr int MON_RADIUS
Definition: mapgen.cpp:103
void apply_function(const string_id< map_extra > &id, map &m, const tripoint &abs_sub)
void run_on_mapgen_postprocess_hooks(lua_state &state, map &m, const tripoint &p, const time_point &when)
Definition: catalua.cpp:425
t_regional_settings_map region_settings_map
Definition: overmap.cpp:186
mtype_id name
Definition: mongroup.h:53
unsigned int chance
weighted_int_list< std::string > values
const std::string & get_extras() const
Definition: omdata.h:237
const overmap_static_spawns & get_static_spawns() const
Definition: omdata.h:245
int get_mondensity() const
Definition: omdata.h:241

References abs_sub, add_spawn(), MapExtras::apply_function(), map_extras::chance, dbg, debugmsg, draw_map(), g, oter_t::get_extras(), DynamicDataLoader::get_instance(), oter_t::get_mondensity(), get_nonant(), oter_t::get_static_spawns(), MonsterGroupManager::GetResultFromGroup(), getsubmap(), Info, MonsterGroupManager::is_animal(), MON_RADIUS, my_MAPSIZE, MonsterGroupResult::name, one_in(), overmap_buffer, MonsterGroupResult::pack_size, passable(), random_point(), region_settings_map, rng(), roll_remainder(), cata::run_on_mapgen_postprocess_hooks(), saven(), set_abs_sub(), setsubmap(), sm_to_omt_copy(), overmapbuffer::ter(), to_string(), map_extras::values, x_in_y(), and tripoint::z.

Referenced by farm_action(), defense_game::init_map(), loadn(), and editmap::mapgen_preview().

◆ generate_lightmap()

void map::generate_lightmap ( int  zlev)
protected

Definition at line 436 of file lightmap.cpp.

437{
438 auto &map_cache = get_cache( zlev );
439 auto &lm = map_cache.lm;
440 auto &sm = map_cache.sm;
441 auto &outside_cache = map_cache.outside_cache;
442 auto &prev_floor_cache = get_cache( clamp( zlev + 1, -OVERMAP_DEPTH, OVERMAP_DEPTH ) ).floor_cache;
443 bool top_floor = zlev == OVERMAP_DEPTH;
444 std::memset( lm, 0, sizeof( lm ) );
445 std::memset( sm, 0, sizeof( sm ) );
446
447 /* Bulk light sources wastefully cast rays into neighbors; a burning hospital can produce
448 significant slowdown, so for stuff like fire and lava:
449 * Step 1: Store the position and luminance in buffer via add_light_source, for efficient
450 checking of neighbors.
451 * Step 2: After everything else, iterate buffer and apply_light_source only in non-redundant
452 directions
453 * Step 3: ????
454 * Step 4: Profit!
455 */
456 auto &light_source_buffer = map_cache.light_source_buffer;
457 std::memset( light_source_buffer, 0, sizeof( light_source_buffer ) );
458
459 constexpr std::array<int, 4> dir_x = { { 0, -1, 1, 0 } }; // [0]
460 constexpr std::array<int, 4> dir_y = { { -1, 0, 0, 1 } }; // [1][X][2]
461 constexpr std::array<int, 4> dir_d = { { 90, 0, 180, 270 } }; // [3]
462 constexpr std::array<std::array<quadrant, 2>, 4> dir_quadrants = { {
467 }
468 };
469
470 const float natural_light = g->natural_light_level( zlev );
471
472 build_sunlight_cache( zlev );
473
475 for( npc &guy : g->all_npcs() ) {
477 }
478
479 std::vector<std::pair<tripoint, float>> lm_override;
480 // Traverse the submaps in order
481 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
482 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
483 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
484
485 for( int sx = 0; sx < SEEX; ++sx ) {
486 for( int sy = 0; sy < SEEY; ++sy ) {
487 const int x = sx + smx * SEEX;
488 const int y = sy + smy * SEEY;
489 const tripoint p( x, y, zlev );
490 // Project light into any openings into buildings.
491 if( !outside_cache[p.x][p.y] || ( !top_floor && prev_floor_cache[p.x][p.y] ) ) {
492 // Apply light sources for external/internal divide
493 for( int i = 0; i < 4; ++i ) {
494 point neighbour = p.xy() + point( dir_x[i], dir_y[i] );
495 if( lightmap_boundaries.contains( neighbour )
496 && outside_cache[neighbour.x][neighbour.y] &&
497 ( top_floor || !prev_floor_cache[neighbour.x][neighbour.y] )
498 ) {
499 const float source_light =
500 std::min( natural_light, lm[neighbour.x][neighbour.y].max() );
502 update_light_quadrants( lm[p.x][p.y], source_light, quadrant::default_ );
503 apply_directional_light( p, dir_d[i], source_light );
504 } else {
505 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][0] );
506 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][1] );
507 }
508 }
509 }
510 }
511
512 if( cur_submap->get_lum( { sx, sy } ) && has_items( p ) ) {
513 auto items = i_at( p );
514 add_light_from_items( p, items.begin(), items.end() );
515 }
516
517 const ter_id terrain = cur_submap->get_ter( { sx, sy } );
518 if( terrain->light_emitted > 0 ) {
519 add_light_source( p, terrain->light_emitted );
520 }
521 const furn_id furniture = cur_submap->get_furn( {sx, sy } );
522 if( furniture->light_emitted > 0 ) {
523 add_light_source( p, furniture->light_emitted );
524 }
525
526 for( auto &fld : cur_submap->get_field( { sx, sy } ) ) {
527 const field_entry *cur = &fld.second;
528 const int light_emitted = cur->light_emitted();
529 if( light_emitted > 0 ) {
530 add_light_source( p, light_emitted );
531 }
532 const float light_override = cur->local_light_override();
533 if( light_override >= 0.0 ) {
534 lm_override.push_back( std::pair<tripoint, float>( p, light_override ) );
535 }
536 }
537 }
538 }
539 }
540 }
541
542 for( monster &critter : g->all_monsters() ) {
543 if( critter.is_hallucination() ) {
544 continue;
545 }
546 const tripoint &mp = critter.pos();
547 if( inbounds( mp ) ) {
548 if( critter.has_effect( effect_onfire ) ) {
549 apply_light_source( mp, 8 );
550 }
551 // TODO: [lightmap] Attach natural light brightness to creatures
552 // TODO: [lightmap] Allow creatures to have light attacks (i.e.: eyebot)
553 // TODO: [lightmap] Allow creatures to have facing and arc lights
554 if( critter.type->luminance > 0 ) {
555 apply_light_source( mp, critter.type->luminance );
556 }
557 }
558 }
559
560 // Apply any vehicle light sources
561 VehicleList vehs = get_vehicles();
562 for( auto &vv : vehs ) {
563 vehicle *v = vv.v;
564
565 auto lights = v->lights( true );
566
567 float veh_luminance = 0.0;
568 float iteration = 1.0;
569
570 for( const auto pt : lights ) {
571 const auto &vp = pt->info();
572 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ||
573 vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
574 veh_luminance += vp.bonus / iteration;
575 iteration = iteration * 1.1;
576 }
577 }
578
579 for( const auto pt : lights ) {
580 const auto &vp = pt->info();
581 tripoint src = v->global_part_pos3( *pt );
582
583 if( !inbounds( src ) ) {
584 continue;
585 }
586
587 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ) {
588 if( veh_luminance > lit_level::LIT ) {
589 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
590 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
591 45_degrees );
592 }
593
594 } else if( vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
595 if( veh_luminance > lit_level::LIT ) {
596 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
597 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
598 90_degrees );
599 }
600
601 } else if( vp.has_flag( VPFLAG_HALF_CIRCLE_LIGHT ) ) {
602 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
603 apply_light_arc( src, v->face.dir() + pt->direction, vp.bonus, 180_degrees );
604
605 } else if( vp.has_flag( VPFLAG_CIRCLE_LIGHT ) ) {
606 const bool odd_turn = calendar::once_every( 2_turns );
607 if( ( odd_turn && vp.has_flag( VPFLAG_ODDTURN ) ) ||
608 ( !odd_turn && vp.has_flag( VPFLAG_EVENTURN ) ) ||
609 ( !( vp.has_flag( VPFLAG_EVENTURN ) || vp.has_flag( VPFLAG_ODDTURN ) ) ) ) {
610
611 add_light_source( src, vp.bonus );
612 }
613
614 } else {
615 add_light_source( src, vp.bonus );
616 }
617 }
618
619 for( const vpart_reference &vp : v->get_all_parts() ) {
620 const size_t p = vp.part_index();
621 const tripoint pp = vp.pos();
622 if( !inbounds( pp ) ) {
623 continue;
624 }
625 if( vp.has_feature( VPFLAG_CARGO ) && !vp.has_feature( "COVERED" ) ) {
626 add_light_from_items( pp, v->get_items( static_cast<int>( p ) ).begin(),
627 v->get_items( static_cast<int>( p ) ).end() );
628 }
629 }
630 }
631
632 /* Now that we have position and intensity of all bulk light sources, apply_ them
633 This may seem like extra work, but take a 12x12 raging inferno:
634 unbuffered: (12^2)*(160*4) = apply_light_ray x 92160
635 buffered: (12*4)*(160) = apply_light_ray x 7680
636 */
637 const tripoint cache_start( 0, 0, zlev );
638 const tripoint cache_end( LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, zlev );
639 for( const tripoint &p : points_in_rectangle( cache_start, cache_end ) ) {
640 if( light_source_buffer[p.x][p.y] > 0.0 ) {
641 apply_light_source( p, light_source_buffer[p.x][p.y] );
642 }
643 }
644 for( const std::pair<tripoint, float> &elem : lm_override ) {
645 lm[elem.first.x][elem.first.y].fill( elem.second );
646 }
647}
float light_emitted() const
Definition: field.cpp:69
float local_light_override() const
Definition: field.cpp:74
float light_transparency(const tripoint &p) const
Definition: lightmap.cpp:696
void apply_directional_light(const tripoint &p, int direction, float luminance)
Definition: lightmap.cpp:1831
void build_sunlight_cache(int pzlev)
Definition: lightmap.cpp:285
void add_light_from_items(const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
Definition: lightmap.cpp:87
void apply_character_light(Character &p)
Definition: lightmap.cpp:263
Definition: npc.h:744
units::angle dir() const
Definition: tileray.cpp:74
std::vector< vehicle_part * > lights(bool active=false)
Get all vehicle lights (excluding any that are destroyed)
Definition: vehicle.cpp:4665
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5491
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
@ VPFLAG_CONE_LIGHT
Definition: veh_type.h:35
@ VPFLAG_CIRCLE_LIGHT
Definition: veh_type.h:38
@ VPFLAG_CARGO
Definition: veh_type.h:62
@ VPFLAG_EVENTURN
Definition: veh_type.h:33
@ VPFLAG_WIDE_CONE_LIGHT
Definition: veh_type.h:36
@ VPFLAG_ODDTURN
Definition: veh_type.h:34
@ VPFLAG_HALF_CIRCLE_LIGHT
Definition: veh_type.h:37

References add_light_from_items(), add_light_source(), apply_character_light(), apply_directional_light(), apply_light_arc(), apply_light_source(), item_stack::begin(), build_sunlight_cache(), clamp(), default_, tileray::dir(), effect_onfire, item_stack::end(), vehicle::face, level_cache::floor_cache, furniture, g, vehicle::get_all_parts(), get_cache(), vehicle::get_items(), get_player_character(), get_submap_at_grid(), get_vehicles(), vehicle::global_part_pos3(), has_items(), i_at(), inbounds(), field_entry::light_emitted(), light_transparency(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, vehicle::lights(), LIT, field_entry::local_light_override(), M_SQRT2, my_MAPSIZE, NE, NW, calendar::once_every(), OVERMAP_DEPTH, points_in_rectangle(), SE, SEEX, SEEY, coords::sm, SW, sx, sy, terrain, update_light_quadrants(), VPFLAG_CARGO, VPFLAG_CIRCLE_LIGHT, VPFLAG_CONE_LIGHT, VPFLAG_EVENTURN, VPFLAG_HALF_CIRCLE_LIGHT, VPFLAG_ODDTURN, VPFLAG_WIDE_CONE_LIGHT, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by build_map_cache().

◆ get_abs_sub()

◆ get_active_items_in_radius() [1/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius 
) const

Definition at line 8788 of file map.cpp.

8790{
8792}
std::list< item_location > get_active_items_in_radius(const tripoint &center, int radius) const
Definition: map.cpp:8788

References center, get_active_items_in_radius(), and none.

Referenced by npc::find_dangerous_explosives(), and get_active_items_in_radius().

◆ get_active_items_in_radius() [2/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius,
special_item_type  type 
) const

Definition at line 8794 of file map.cpp.

8796{
8797 std::list<item_location> result;
8798
8799 const point minp( center.xy() + point( -radius, -radius ) );
8800 const point maxp( center.xy() + point( radius, radius ) );
8801
8802 const point ming( std::max( minp.x / SEEX, 0 ),
8803 std::max( minp.y / SEEY, 0 ) );
8804 const point maxg( std::min( maxp.x / SEEX, my_MAPSIZE - 1 ),
8805 std::min( maxp.y / SEEY, my_MAPSIZE - 1 ) );
8806
8807 for( const tripoint &abs_submap_loc : submaps_with_active_items ) {
8808 const tripoint submap_loc{ -abs_sub.xy() + abs_submap_loc };
8809 if( submap_loc.x < ming.x || submap_loc.y < ming.y ||
8810 submap_loc.x > maxg.x || submap_loc.y > maxg.y ) {
8811 continue;
8812 }
8813 const point sm_offset( submap_loc.x * SEEX, submap_loc.y * SEEY );
8814
8815 submap *sm = get_submap_at_grid( submap_loc );
8816 std::vector<item_reference> items = type == special_item_type::none ? sm->active_items.get() :
8817 sm->active_items.get_special( type );
8818 for( const auto &elem : items ) {
8819 const tripoint pos( sm_offset + elem.location, submap_loc.z );
8820
8821 if( rl_dist( pos, center ) > radius ) {
8822 continue;
8823 }
8824
8825 if( elem.item_ref ) {
8826 result.emplace_back( map_cursor( pos ), elem.item_ref.get() );
8827 }
8828 }
8829 }
8830
8831 return result;
8832}

References abs_sub, center, get_submap_at_grid(), my_MAPSIZE, none, rl_dist(), SEEX, SEEY, coords::sm, submaps_with_active_items, type, point::x, tripoint::xy(), and point::y.

◆ get_cache()

◆ get_cache_ref()

◆ get_creatures_in_radius()

std::list< Creature * > map::get_creatures_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
)

returns creatures in specified radius

Definition at line 8876 of file map.cpp.

8878{
8879 std::list<Creature *> creatures;
8880 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8881 Creature *tmp_critter = g->critter_at( loc );
8882 if( tmp_critter != nullptr ) {
8883 creatures.push_back( tmp_critter );
8884 }
8885
8886 }
8887 return creatures;
8888}

References center, g, and points_in_radius().

◆ get_dir_circle()

std::vector< tripoint > map::get_dir_circle ( const tripoint f,
const tripoint t 
) const

Calculate next search points surrounding the current position.

Points closer to the target come first. This method leads to straighter lines and prevents weird looking movements away from the target.

Definition at line 6701 of file map.cpp.

6702{
6703 std::vector<tripoint> circle;
6704 circle.resize( 8 );
6705
6706 // The line below can be crazy expensive - we only take the FIRST point of it
6707 const std::vector<tripoint> line = line_to( f, t, 0, 0 );
6708 const std::vector<tripoint> spiral = closest_points_first( f, 1 );
6709 const std::vector<int> pos_index {1, 2, 4, 6, 8, 7, 5, 3};
6710
6711 // All possible constellations (closest_points_first goes clockwise)
6712 // 753 531 312 124 246 468 687 875
6713 // 8 1 7 2 5 4 3 6 1 8 2 7 4 5 6 3
6714 // 642 864 786 578 357 135 213 421
6715
6716 size_t pos_offset = 0;
6717 for( size_t i = 1; i < spiral.size(); i++ ) {
6718 if( spiral[i] == line[0] ) {
6719 pos_offset = i - 1;
6720 break;
6721 }
6722 }
6723
6724 for( size_t i = 1; i < spiral.size(); i++ ) {
6725 if( pos_offset >= pos_index.size() ) {
6726 pos_offset = 0;
6727 }
6728
6729 circle[pos_index[pos_offset++] - 1] = spiral[i];
6730 }
6731
6732 return circle;
6733}
void circle(map *m, const ter_id &type, double x, double y, double rad)
Definition: mapgen.cpp:6330

References circle(), closest_points_first(), line(), and line_to().

◆ get_field() [1/2]

field & map::get_field ( const tripoint p)
private

Definition at line 8624 of file map.cpp.

8625{
8626 return field_at( p );
8627}

References field_at().

◆ get_field() [2/2]

field_entry * map::get_field ( const tripoint p,
const field_type_id type 
)

Get field of specific type at point.

Returns
NULL if there is no such field entry at that place.

Definition at line 5513 of file map.cpp.

5514{
5515 if( !inbounds( p ) || !has_field_at( p, false ) ) {
5516 return nullptr;
5517 }
5518
5519 point l;
5520 submap *const current_submap = get_submap_at( p, l );
5521
5522 return current_submap->get_field( l ).find_field( type );
5523}
bool has_field_at(const tripoint &p, bool check_bounds=true)
Definition: map.cpp:5507

References field::find_field(), submap::get_field(), get_submap_at(), has_field_at(), inbounds(), and type.

Referenced by add_item(), bash_field(), creature_in_field(), has_nearby_fire(), monster_in_field(), player_in_field(), process_fields_in_submap(), set_field_age(), set_field_intensity(), and shoot().

◆ get_field_age()

time_duration map::get_field_age ( const tripoint p,
const field_type_id type 
) const

Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns.

Definition at line 5494 of file map.cpp.

5495{
5496 auto field_ptr = field_at( p ).find_field( type );
5497 return field_ptr == nullptr ? -1_turns : field_ptr->get_field_age();
5498}

References field_at(), field::find_field(), field_entry::get_field_age(), and type.

Referenced by game::grabbed_furn_move(), and game::walk_move().

◆ get_field_intensity()

int map::get_field_intensity ( const tripoint p,
const field_type_id type 
) const

Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0.

Definition at line 5500 of file map.cpp.

5501{
5502 auto field_ptr = field_at( p ).find_field( type );
5503 return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() );
5504}

References field_at(), field::find_field(), and type.

Referenced by game::grabbed_furn_move(), is_flammable(), propagate_field(), fungal_effects::spread_fungus_one_tile(), and game::walk_move().

◆ get_furn_field_locations()

const std::vector< tripoint > & map::get_furn_field_locations ( ) const

Definition at line 7888 of file map.cpp.

7889{
7890 return field_furn_locs;
7891}

References field_furn_locs.

Referenced by game::do_turn().

◆ get_furn_transforms_into()

furn_id map::get_furn_transforms_into ( const tripoint p) const

Definition at line 1677 of file map.cpp.

1678{
1679 return furn( p ).obj().transforms_into.id();
1680}
furn_str_id transforms_into
Definition: mapdata.h:507

References furn(), string_id< T >::id(), int_id< T >::obj(), and furn_t::transforms_into.

◆ get_harvest()

const harvest_id & map::get_harvest ( const tripoint p) const

Returns the full harvest list, for spawning.

Definition at line 1629 of file map.cpp.

1630{
1631 const auto furn_here = furn( pos );
1632 if( furn_here->examine != iexamine::none ) {
1633 // Note: if furniture can be examined, the terrain can NOT (until furniture is removed)
1634 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1635 return harvest_id::NULL_ID();
1636 }
1637
1638 return furn_here->get_harvest();
1639 }
1640
1641 const auto ter_here = ter( pos );
1642 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1643 return harvest_id::NULL_ID();
1644 }
1645
1646 return ter_here->get_harvest();
1647}
static const string_id< harvest_list > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
@ TFLAG_HARVESTED
Definition: mapdata.h:304

References furn(), iexamine::none(), string_id< harvest_list >::NULL_ID(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by is_harvestable().

◆ get_harvest_names()

const std::set< std::string > & map::get_harvest_names ( const tripoint p) const

Returns names of the items that would be dropped.

Definition at line 1649 of file map.cpp.

1650{
1651 static const std::set<std::string> null_harvest_names = {};
1652 const auto furn_here = furn( pos );
1653 if( furn_here->examine != iexamine::none ) {
1654 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1655 return null_harvest_names;
1656 }
1657
1658 return furn_here->get_harvest_names();
1659 }
1660
1661 const auto ter_here = ter( pos );
1662 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1663 return null_harvest_names;
1664 }
1665
1666 return ter_here->get_harvest_names();
1667}

References furn(), iexamine::none(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

◆ get_known_connections()

uint8_t map::get_known_connections ( const tripoint p,
int  connect_group,
const std::map< tripoint, ter_id > &  override = {} 
) const

Definition at line 1575 of file map.cpp.

1577{
1578 auto &ch = access_cache( p.z );
1579 uint8_t val = 0;
1580 std::function<bool( const tripoint & )> is_memorized;
1581#ifdef TILES
1582 if( use_tiles ) {
1583 is_memorized =
1584 [&]( const tripoint & q ) {
1585 return !g->u.get_memorized_tile( getabs( q ) ).tile.empty();
1586 };
1587 } else {
1588#endif
1589 is_memorized =
1590 [&]( const tripoint & q ) {
1591 return g->u.get_memorized_symbol( getabs( q ) );
1592 };
1593#ifdef TILES
1594 }
1595#endif
1596
1597 const bool overridden = override.find( p ) != override.end();
1598 const bool is_transparent = ch.transparency_cache[p.x][p.y] > LIGHT_TRANSPARENCY_SOLID;
1599
1600 // populate connection information
1601 for( int i = 0; i < 4; ++i ) {
1602 tripoint neighbour = p + offsets[i];
1603 if( !inbounds( neighbour ) ) {
1604 continue;
1605 }
1606 const auto neighbour_override = override.find( neighbour );
1607 const bool neighbour_overridden = neighbour_override != override.end();
1608 // if there's some non-memory terrain to show at the neighboring tile
1609 const bool may_connect = neighbour_overridden ||
1610 get_visibility( ch.visibility_cache[neighbour.x][neighbour.y],
1612 // or if an actual center tile is transparent or next to a memorized tile
1613 ( !overridden && ( is_transparent || is_memorized( neighbour ) ) );
1614 if( may_connect ) {
1615 const ter_t &neighbour_terrain = neighbour_overridden ?
1616 neighbour_override->second.obj() : ter( neighbour ).obj();
1617 if( neighbour_terrain.connects_to( connect_group ) ) {
1618 val += 1 << i;
1619 }
1620 }
1621 }
1622
1623 return val;
1624}
bool use_tiles
Use tiles for display.
bool is_transparent(const tripoint &p) const
Returns whether the tile at p is transparent(you can look past it).
Definition: lightmap.cpp:691
level_cache & access_cache(int zlev)
Definition: map.cpp:8890
static constexpr std::array< point, 4 > offsets
Definition: point.h:361
bool connects_to(int test_connect_group) const
Definition: mapdata.h:437

References access_cache(), map_data_common_t::connects_to(), g, get_visibility(), get_visibility_variables_cache(), getabs(), inbounds(), is_transparent(), LIGHT_TRANSPARENCY_SOLID, int_id< T >::obj(), offsets, ter(), use_tiles, VIS_CLEAR, tripoint::x, tripoint::y, and tripoint::z.

Referenced by determine_wall_corner().

◆ get_neighbors()

std::array< std::pair< tripoint, maptile >, 8 > map::get_neighbors ( const tripoint p)
private

Definition at line 191 of file map_field.cpp.

192{
193 // Find out which edges are in the bubble
194 // Where possible, do just one bounds check for all the neighbors
195 const bool west = p.x > 0;
196 const bool north = p.y > 0;
197 const bool east = p.x < SEEX * my_MAPSIZE - 1;
198 const bool south = p.y < SEEY * my_MAPSIZE - 1;
199 return std::array< std::pair<tripoint, maptile>, 8 > { {
200 maptile_has_bounds( p + eight_horizontal_neighbors[0], west &&north ),
202 maptile_has_bounds( p + eight_horizontal_neighbors[2], east &&north ),
205 maptile_has_bounds( p + eight_horizontal_neighbors[5], west &&south ),
207 maptile_has_bounds( p + eight_horizontal_neighbors[7], east &&south ),
208 }
209 };
210}
std::pair< tripoint, maptile > maptile_has_bounds(const tripoint &p, bool bounds_checked)
Definition: map_field.cpp:181
static const std::array< tripoint, 8 > eight_horizontal_neighbors
Definition: point.h:379

References eight_horizontal_neighbors, maptile_has_bounds(), my_MAPSIZE, SEEX, SEEY, tripoint::x, and tripoint::y.

Referenced by process_fields_in_submap(), and spread_gas().

◆ get_nonant() [1/2]

size_t map::get_nonant ( const tripoint gridp) const
protected

Get the index of a submap pointer in the grid given by grid coordinates.

The grid coordinates must be valid: 0 <= x < my_MAPSIZE, same for y. Version with z-levels checks for z between -OVERMAP_DEPTH and OVERMAP_HEIGHT

Definition at line 8480 of file map.cpp.

8481{
8482 // There used to be a bounds check here
8483 // But this function is called a lot, so push it up if needed
8484 if( zlevels ) {
8485 const int indexz = gridp.z + OVERMAP_HEIGHT; // Can't be lower than 0
8486 return indexz + ( gridp.x + gridp.y * my_MAPSIZE ) * OVERMAP_LAYERS;
8487 } else {
8488 return gridp.x + gridp.y * my_MAPSIZE;
8489 }
8490}

References my_MAPSIZE, OVERMAP_HEIGHT, OVERMAP_LAYERS, tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by copy_grid(), fake_map::fake_map(), generate(), get_nonant(), get_submap_at_grid(), loadn(), and saven().

◆ get_nonant() [2/2]

size_t map::get_nonant ( point  gridp) const
inlineprotected

Definition at line 1847 of file map.h.

1847 {
1848 return get_nonant( { gridp, abs_sub.z } );
1849 }

References abs_sub, get_nonant(), and tripoint::z.

◆ get_pathfinding_cache()

pathfinding_cache & map::get_pathfinding_cache ( int  zlev) const
private

Definition at line 8940 of file map.cpp.

8941{
8942 return *pathfinding_caches[zlev + OVERMAP_DEPTH];
8943}

References OVERMAP_DEPTH, and pathfinding_caches.

Referenced by get_pathfinding_cache_ref(), set_pathfinding_cache_dirty(), and update_pathfinding_cache().

◆ get_pathfinding_cache_ref()

const pathfinding_cache & map::get_pathfinding_cache_ref ( int  zlev) const

Definition at line 8990 of file map.cpp.

8991{
8992 if( !inbounds_z( zlev ) ) {
8993 debugmsg( "Tried to get pathfinding cache for out of bounds z-level %d", zlev );
8995 }
8996 auto &cache = get_pathfinding_cache( zlev );
8997 if( cache.dirty ) {
8999 }
9000
9001 return cache;
9002}
void update_pathfinding_cache(int zlev) const
Definition: map.cpp:9004
bool inbounds_z(const int z) const
Definition: map.h:1628
pathfinding_cache & get_pathfinding_cache(int zlev) const
Definition: map.cpp:8940

References debugmsg, get_pathfinding_cache(), inbounds_z(), OVERMAP_DEPTH, pathfinding_caches, and update_pathfinding_cache().

Referenced by route(), and vertical_move_destination().

◆ get_radiation()

int map::get_radiation ( const tripoint p) const

Definition at line 4154 of file map.cpp.

4155{
4156 if( !inbounds( p ) ) {
4157 return 0;
4158 }
4159
4160 point l;
4161 submap *const current_submap = get_submap_at( p, l );
4162
4163 return current_submap->get_radiation( l );
4164}

References submap::get_radiation(), get_submap_at(), and inbounds().

Referenced by relic_funcs::check_recharge_reqs(), editmap::draw_main_ui_overlay(), and rad_scorch().

◆ get_roof()

ter_id map::get_roof ( const tripoint p,
bool  allow_air 
) const
private

Definition at line 3202 of file map.cpp.

3203{
3204 // This function should not be called from the 2D mode
3205 // Just use t_dirt instead
3206 assert( zlevels );
3207
3208 if( p.z <= -OVERMAP_DEPTH ) {
3209 // Could be magma/"void" instead
3210 return t_rock_floor;
3211 }
3212
3213 const auto &ter_there = ter( p ).obj();
3214 const auto &roof = ter_there.roof;
3215 if( !roof ) {
3216 // No roof
3217 if( !allow_air ) {
3218 // TODO: Biomes? By setting? Forbid and treat as bug?
3219 if( p.z < 0 ) {
3220 return t_rock_floor_no_roof;
3221 }
3222
3223 return t_dirt;
3224 }
3225
3226 return t_open_air;
3227 }
3228
3229 ter_id new_ter = roof.id();
3230 if( new_ter == t_null ) {
3231 debugmsg( "map::get_new_floor: %d,%d,%d has invalid roof type %s",
3232 p.x, p.y, p.z, roof.c_str() );
3233 return t_dirt;
3234 }
3235
3236 if( p.z == -1 && new_ter == t_rock_floor ) {
3237 // HACK: A hack to work around not having a "solid earth" tile
3238 new_ter = t_dirt;
3239 }
3240
3241 return new_ter;
3242}
static const ter_str_id t_rock_floor_no_roof("t_rock_floor_no_roof")

References debugmsg, int_id< T >::id(), int_id< T >::obj(), OVERMAP_DEPTH, ter_t::roof, t_dirt, t_null, t_open_air, t_rock_floor, t_rock_floor_no_roof, ter(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by bash_ter_furn(), and bash_ter_success().

◆ get_signage()

std::string map::get_signage ( const tripoint p) const

Definition at line 4120 of file map.cpp.

4121{
4122 if( !inbounds( p ) ) {
4123 return "";
4124 }
4125
4126 point l;
4127 submap *const current_submap = get_submap_at( p, l );
4128
4129 return current_submap->get_signage( l );
4130}
std::string get_signage(point p) const
Definition: submap.cpp:162

References submap::get_signage(), get_submap_at(), and inbounds().

Referenced by game::extended_description(), game::place_player(), and game::print_terrain_info().

◆ get_submap_at() [1/4]

◆ get_submap_at() [2/4]

submap * map::get_submap_at ( const tripoint p,
point offset_p 
) const
private

Get the submap pointer containing the specified position within the reality bubble.

The same as other get_submap_at, (p) must be valid (inbounds). Also writes the position within the submap to offset_p

Definition at line 8468 of file map.cpp.

8469{
8470 offset_p.x = p.x % SEEX;
8471 offset_p.y = p.y % SEEY;
8472 return get_submap_at( p );
8473}

References get_submap_at(), SEEX, SEEY, point::x, tripoint::x, point::y, and tripoint::y.

◆ get_submap_at() [3/4]

submap * map::get_submap_at ( point  p) const
inlineprivate

Definition at line 1819 of file map.h.

1819 {
1820 return get_submap_at( tripoint( p, abs_sub.z ) );
1821 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [4/4]

submap * map::get_submap_at ( point  p,
point offset_p 
) const
inlineprivate

Definition at line 1828 of file map.h.

1828 {
1829 return get_submap_at( { p, abs_sub.z }, offset_p );
1830 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at_grid() [1/2]

submap * map::get_submap_at_grid ( const tripoint gridp) const
private

Definition at line 8475 of file map.cpp.

8476{
8477 return getsubmap( get_nonant( gridp ) );
8478}

References get_nonant(), and getsubmap().

◆ get_submap_at_grid() [2/2]

◆ get_submaps_with_active_items()

const std::set< tripoint > & map::get_submaps_with_active_items ( ) const
inline

Definition at line 2020 of file map.h.

2020 {
2022 }

References submaps_with_active_items.

◆ get_temperature()

int map::get_temperature ( const tripoint p) const

Definition at line 4191 of file map.cpp.

4192{
4193 if( !inbounds( p ) ) {
4194 return 0;
4195 }
4196
4197 return get_submap_at( p )->get_temperature();
4198}
int get_temperature() const
Definition: submap.h:165

References get_submap_at(), submap::get_temperature(), and inbounds().

◆ get_ter_transforms_into()

ter_id map::get_ter_transforms_into ( const tripoint p) const

Definition at line 1672 of file map.cpp.

1673{
1674 return ter( p ).obj().transforms_into.id();
1675}
ter_str_id transforms_into
Definition: mapdata.h:472

References string_id< T >::id(), int_id< T >::obj(), ter(), and ter_t::transforms_into.

◆ get_vehicle_zones()

std::vector< zone_data * > map::get_vehicle_zones ( int  zlev)

Definition at line 999 of file map.cpp.

1000{
1001 std::vector<zone_data *> veh_zones;
1002 bool rebuild = false;
1003 for( auto veh : get_cache( zlev ).zone_vehicles ) {
1004 if( veh->refresh_zones() ) {
1005 rebuild = true;
1006 }
1007 for( auto &zone : veh->loot_zones ) {
1008 veh_zones.emplace_back( &zone.second );
1009 }
1010 }
1011 if( rebuild ) {
1013 }
1014 return veh_zones;
1015}
static zone_manager & get_manager()
Definition: clzones.cpp:127
void cache_vzones()
Definition: clzones.cpp:625

References zone_manager::cache_vzones(), get_cache(), and zone_manager::get_manager().

Referenced by zone_manager::cache_vzones(), zone_manager::get_bottom_zone(), zone_manager::get_zone_at(), and zone_manager::get_zones().

◆ get_vehicles() [1/2]

◆ get_vehicles() [2/2]

VehicleList map::get_vehicles ( const tripoint start,
const tripoint end 
)

Definition at line 1040 of file map.cpp.

1041{
1042 const int chunk_sx = std::max( 0, ( start.x / SEEX ) - 1 );
1043 const int chunk_ex = std::min( my_MAPSIZE - 1, ( end.x / SEEX ) + 1 );
1044 const int chunk_sy = std::max( 0, ( start.y / SEEY ) - 1 );
1045 const int chunk_ey = std::min( my_MAPSIZE - 1, ( end.y / SEEY ) + 1 );
1046 const int chunk_sz = start.z;
1047 const int chunk_ez = end.z;
1048 VehicleList vehs;
1049
1050 for( int cx = chunk_sx; cx <= chunk_ex; ++cx ) {
1051 for( int cy = chunk_sy; cy <= chunk_ey; ++cy ) {
1052 for( int cz = chunk_sz; cz <= chunk_ez; ++cz ) {
1053 submap *current_submap = get_submap_at_grid( { cx, cy, cz } );
1054 for( const auto &elem : current_submap->vehicles ) {
1055 // Ensure the vehicle z-position is correct
1056 elem->sm_pos.z = cz;
1058 w.v = elem.get();
1059 w.pos = w.v->global_pos3();
1060 vehs.push_back( w );
1061 }
1062 }
1063 }
1064 }
1065
1066 return vehs;
1067}
tripoint pos
Definition: map.h:81
vehicle * v
Definition: map.h:82

References get_submap_at_grid(), vehicle::global_pos3(), my_MAPSIZE, wrapped_vehicle::pos, SEEX, SEEY, wrapped_vehicle::v, submap::vehicles, tripoint::x, tripoint::y, and tripoint::z.

◆ get_visibility()

visibility_type map::get_visibility ( lit_level  ll,
const visibility_variables cache 
) const

Definition at line 5790 of file map.cpp.

5792{
5793 switch( ll ) {
5794 case lit_level::DARK:
5795 // can't see this square at all
5796 if( cache.u_is_boomered ) {
5797 return VIS_BOOMER_DARK;
5798 } else {
5799 return VIS_DARK;
5800 }
5802 // can only tell that this square is bright
5803 if( cache.u_is_boomered ) {
5804 return VIS_BOOMER;
5805 } else {
5806 return VIS_LIT;
5807 }
5808
5809 case lit_level::LOW:
5810 // low light, square visible in monochrome
5811 case lit_level::LIT:
5812 // normal light
5813 case lit_level::BRIGHT:
5814 // bright light
5815 return VIS_CLEAR;
5816 case lit_level::BLANK:
5818 return VIS_HIDDEN;
5819 }
5820 return VIS_HIDDEN;
5821}
bool u_is_boomered
Definition: map.h:124

References BLANK, BRIGHT, BRIGHT_ONLY, DARK, LIT, LOW, MEMORIZED, visibility_variables::u_is_boomered, VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, and VIS_LIT.

Referenced by draw(), game::draw_look_around_cursor(), generate_weather_anim_frame(), get_known_connections(), and game::print_all_tile_info().

◆ get_visibility_variables_cache()

const visibility_variables & map::get_visibility_variables_cache ( ) const

Definition at line 5785 of file map.cpp.

5786{
5788}
visibility_variables visibility_variables_cache
Definition: map.h:1999

References visibility_variables_cache.

Referenced by draw(), generate_weather_anim_frame(), get_known_connections(), game::look_around(), and live_view::show().

◆ get_wind_blockers()

std::tuple< maptile, maptile, maptile > map::get_wind_blockers ( const int &  winddirection,
const tripoint pos 
)

Definition at line 1894 of file map_field.cpp.

1896{
1897 static const std::array<std::pair<int, std::tuple< point, point, point >>, 9> outputs = {{
1898 { 330, std::make_tuple( point_east, point_north_east, point_south_east ) },
1899 { 301, std::make_tuple( point_south_east, point_east, point_south ) },
1900 { 240, std::make_tuple( point_south, point_south_west, point_south_east ) },
1901 { 211, std::make_tuple( point_south_west, point_west, point_south ) },
1902 { 150, std::make_tuple( point_west, point_north_west, point_south_west ) },
1903 { 121, std::make_tuple( point_north_west, point_north, point_west ) },
1904 { 60, std::make_tuple( point_north, point_north_west, point_north_east ) },
1905 { 31, std::make_tuple( point_north_east, point_east, point_north ) },
1906 { 0, std::make_tuple( point_east, point_north_east, point_south_east ) }
1907 }
1908 };
1909
1910 tripoint removepoint;
1911 tripoint removepoint2;
1912 tripoint removepoint3;
1913 for( const std::pair<int, std::tuple< point, point, point >> &val : outputs ) {
1914 if( winddirection >= val.first ) {
1915 removepoint = pos + std::get<0>( val.second );
1916 removepoint2 = pos + std::get<1>( val.second );
1917 removepoint3 = pos + std::get<2>( val.second );
1918 break;
1919 }
1920 }
1921
1922 const maptile remove_tile = maptile_at( removepoint );
1923 const maptile remove_tile2 = maptile_at( removepoint2 );
1924 const maptile remove_tile3 = maptile_at( removepoint3 );
1925 return std::make_tuple( remove_tile, remove_tile2, remove_tile3 );
1926}

References maptile_at(), point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, and point_west.

Referenced by spread_gas().

◆ getabs() [1/2]

tripoint map::getabs ( const tripoint p) const

Translates local (to this map) coordinates of a square to global absolute coordinates.

Coordinates is in the system that is used by the ter/furn/i_at functions. Output is in the same scale, but in global system.

Definition at line 8407 of file map.cpp.

8408{
8409 return sm_to_ms_copy( abs_sub.xy() ) + p;
8410}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by add_item(), Character::add_known_trap(), jmapgen_zone::apply(), game::autopilot_vehicles(), bash_ter_furn(), game::check_near_zone(), game::check_zone(), game::control_vehicle(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), npc::do_pulp(), draw_maptile(), fill_funnels(), game::find_or_make_stairs(), find_valid_teleporters_omt(), inventory::form_from_map(), furn_set(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_known_connections(), getabs(), getglobal(), Character::global_square_location(), game::grabbed_furn_move(), grow_plant(), npc::guard_current_pos(), Character::knows_trap(), game::place_player(), game::place_vehicle_nearby(), iexamine::plant_seed(), game::pre_print_all_tile_info(), sounds::process_sounds(), zone_manager::rotate_zones(), target_ui::set_last_target(), shoot(), spawn_monsters_submap_group(), ter_set(), translate_radius(), update_suspension_cache(), use_charges_from_furn(), iexamine::use_furn_fake_item(), vertical_move_destination(), and game::zones_manager().

◆ getabs() [2/2]

point map::getabs ( point  p) const
inline

Definition at line 1611 of file map.h.

1611 {
1612 return getabs( tripoint( p, abs_sub.z ) ).xy();
1613 }

References abs_sub, getabs(), tripoint::xy(), and tripoint::z.

◆ getglobal()

tripoint_abs_ms map::getglobal ( const tripoint p) const

Definition at line 8412 of file map.cpp.

8413{
8414 return tripoint_abs_ms( getabs( p ) );
8415}

References getabs().

◆ getlocal() [1/3]

◆ getlocal() [2/3]

tripoint map::getlocal ( const tripoint_abs_ms p) const

Definition at line 8422 of file map.cpp.

8423{
8424 // TODO: fix point types
8425 return getlocal( p.raw() );
8426}
constexpr Point & raw()
Definition: coordinates.h:111

References getlocal(), and coords::coord_point< Point, Origin, Scale >::raw().

◆ getlocal() [3/3]

point map::getlocal ( point  p) const
inline

Definition at line 1619 of file map.h.

1619 {
1620 return getlocal( tripoint( p, abs_sub.z ) ).xy();
1621 }

References abs_sub, getlocal(), tripoint::xy(), and tripoint::z.

◆ getmapsize()

int map::getmapsize ( ) const
inline

Definition at line 1637 of file map.h.

1637 {
1638 return my_MAPSIZE;
1639 }

References my_MAPSIZE.

Referenced by distribution_grid_tracker::load(), and points_in_range().

◆ getsubmap()

submap * map::getsubmap ( size_t  grididx) const
private

Get the submap pointer with given index in grid, the index must be valid!

Definition at line 8438 of file map.cpp.

8439{
8440 if( grididx >= grid.size() ) {
8441 debugmsg( "Tried to access invalid grid index %d. Grid size: %d", grididx, grid.size() );
8442 return nullptr;
8443 }
8444 return grid[grididx];
8445}

References debugmsg, and grid.

Referenced by generate(), get_submap_at_grid(), and saven().

◆ graffiti_at()

const std::string & map::graffiti_at ( const tripoint p) const

Definition at line 7969 of file map.cpp.

7970{
7971 if( !inbounds( p ) ) {
7972 static const std::string empty_string;
7973 return empty_string;
7974 }
7975 point l;
7976 submap *const current_submap = get_submap_at( p, l );
7977 return current_submap->get_graffiti( l );
7978}
const std::string & get_graffiti(point p) const
Definition: submap.cpp:124

References submap::get_graffiti(), get_submap_at(), and inbounds().

Referenced by game::place_player(), and game::print_graffiti_info().

◆ grow_plant()

void map::grow_plant ( const tripoint p)
protected

Try to grow a harvestable plant to the next stage(s).

Definition at line 7292 of file map.cpp.

7293{
7294 const auto &furn = this->furn( p ).obj();
7295 if( !furn.has_flag( "PLANT" ) ) {
7296 return;
7297 }
7298 // Can't use item_stack::only_item() since there might be fertilizer
7299 map_stack items = i_at( p );
7300 map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
7301 return it.is_seed();
7302 } );
7303
7304 if( seed == items.end() ) {
7305 // No seed there anymore, we don't know what kind of plant it was.
7306 // TODO: Fix point types
7307 const oter_id ot = overmap_buffer.ter( project_to<coords::omt>( tripoint_abs_ms( getabs( p ) ) ) );
7308 dbg( DL::Error ) << "a planted item at " << p
7309 << " (within overmap terrain " << ot.id().str() << ") has no seed data";
7310 i_clear( p );
7311 furn_set( p, f_null );
7312 return;
7313 }
7314 const time_duration plantEpoch = seed->get_plant_epoch();
7315 if( seed->age() >= plantEpoch * furn.plant->growth_multiplier &&
7316 !furn.has_flag( "GROWTH_HARVEST" ) ) {
7317 if( seed->age() < plantEpoch * 2 ) {
7318 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7319 return;
7320 }
7321
7322 // Remove fertilizer if any
7323 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7324 return it.has_flag( "FERTILIZER" );
7325 } );
7326 if( fertilizer != items.end() ) {
7327 items.erase( fertilizer );
7328 }
7329
7330 rotten_item_spawn( *seed, p );
7331 furn_set( p, furn_str_id( furn.plant->transform ) );
7332 } else if( seed->age() < plantEpoch * 3 * furn.plant->growth_multiplier ) {
7333 if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7334 return;
7335 }
7336
7337 // Remove fertilizer if any
7338 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7339 return it.has_flag( "FERTILIZER" );
7340 } );
7341 if( fertilizer != items.end() ) {
7342 items.erase( fertilizer );
7343 }
7344
7345 rotten_item_spawn( *seed, p );
7346 //You've skipped the seedling stage so roll monsters twice
7347 if( !has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7348 rotten_item_spawn( *seed, p );
7349 }
7350 furn_set( p, furn_str_id( furn.plant->transform ) );
7351 } else {
7352 //You've skipped two stages so roll monsters two times
7353 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7354 rotten_item_spawn( *seed, p );
7355 rotten_item_spawn( *seed, p );
7356 //One stage change
7357 } else if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7358 rotten_item_spawn( *seed, p );
7359 //Goes from seed to harvest in one check
7360 } else {
7361 rotten_item_spawn( *seed, p );
7362 rotten_item_spawn( *seed, p );
7363 rotten_item_spawn( *seed, p );
7364 }
7365 furn_set( p, furn_str_id( furn.plant->transform ) );
7366 }
7367 }
7368}
iterator erase(const_iterator it) override
Definition: map.cpp:154
void rotten_item_spawn(const item &item, const tripoint &p)
Checks to see if the item that is rotting away generates a creature when it does.
Definition: map.cpp:7244
string_id< furn_t > furn_str_id
Definition: type_id.h:65

References item_stack::begin(), dbg, item_stack::end(), map_stack::erase(), Error, f_null, furn(), furn_set(), getabs(), has_flag_furn(), i_at(), i_clear(), int_id< T >::id(), int_id< T >::obj(), overmap_buffer, rotten_item_spawn(), iuse::seed(), string_id< T >::str(), and overmapbuffer::ter().

Referenced by actualize().

◆ has_adjacent_furniture_with()

bool map::has_adjacent_furniture_with ( const tripoint p,
const std::function< bool(const furn_t &)> &  filter 
)

Returns true if there is furniture for which filter returns true in a 1 tile radius of p.

Pass return_true<furn_t> to detect all adjacent furniture.

Parameters
pthe location to check at
filterwhat to filter the furniture by.

Definition at line 2804 of file map.cpp.

2806{
2807 for( const tripoint &adj : points_in_radius( p, 1 ) ) {
2808 if( has_furn( adj ) && filter( furn( adj ).obj() ) ) {
2809 return true;
2810 }
2811 }
2812
2813 return false;
2814}

References furn(), has_furn(), and points_in_radius().

◆ has_field_at()

bool map::has_field_at ( const tripoint p,
bool  check_bounds = true 
)
Returns
true if there might be a field at p
false there's no fields at p

Definition at line 5507 of file map.cpp.

5508{
5509 const tripoint sm = ms_to_sm_copy( p );
5510 return ( !check_bounds || inbounds( p ) ) && get_cache( p.z ).field_cache[sm.x + sm.y * MAPSIZE];
5511}

References level_cache::field_cache, get_cache(), inbounds(), MAPSIZE, ms_to_sm_copy(), coords::sm, and tripoint::z.

Referenced by get_field().

◆ has_flag() [1/4]

bool map::has_flag ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2375 of file map.cpp.

2376{
2377 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2378}

References has_flag_ter_or_furn().

Referenced by accessible_items(), add_item(), add_item_or_charges(), bash(), bash_ter_furn(), bash_ter_success(), start_location::burn(), game::butcher(), can_put_items_ter_furn(), climb_difficulty(), close_door(), doors::close_door(), collapse_at(), collapse_check(), displace_water(), dont_draw_lower_floor(), draw_lab(), drop_everything(), game::examine(), features(), find_furnitures_or_vparts_with_flag_in_radius(), game::find_or_make_stairs(), flammable_items_at(), game::fling_creature(), game::forced_door_closing(), game::get_dangerous_tile(), game::get_fishable_locations(), game::grabbed_furn_move(), has_flag(), has_nearby_chair(), has_nearby_table(), hit_with_fire(), is_divable(), game::is_empty(), is_flammable(), is_water_shallow_current(), game::knockback(), mop_spills(), avatar_action::move(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_minefield(), item::on_drop(), open_door(), game::place_player(), game::print_fields_info(), game::print_items_info(), process_fields_in_submap(), propagate_field(), propagate_suspension_check(), avatar_action::ramp_move(), rate_location(), route(), shoot(), spawn_an_item(), spawn_items(), fungal_effects::spread_fungus(), fungal_effects::spread_fungus_one_tile(), avatar_action::swim(), game::update_stair_monsters(), use_charges_from_furn(), game::use_computer(), game::vertical_move(), vertical_move_destination(), game::walk_move(), and water_from().

◆ has_flag() [2/4]

bool map::has_flag ( const std::string &  flag,
point  p 
) const
inline

Definition at line 904 of file map.h.

904 {
905 return has_flag( flag, tripoint( p, abs_sub.z ) );
906 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [3/4]

bool map::has_flag ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2418 of file map.cpp.

2419{
2420 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2421}

References has_flag_ter_or_furn().

◆ has_flag() [4/4]

bool map::has_flag ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 939 of file map.h.

939 {
940 return has_flag( flag, tripoint( p, abs_sub.z ) );
941 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag_furn() [1/4]

bool map::has_flag_furn ( const std::string &  flag,
const tripoint p 
) const

◆ has_flag_furn() [2/4]

bool map::has_flag_furn ( const std::string &  flag,
point  p 
) const
inline

Definition at line 924 of file map.h.

924 {
925 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
926 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [3/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2428 of file map.cpp.

2429{
2430 return furn( p ).obj().has_flag( flag );
2431}

References furn(), map_data_common_t::has_flag(), and int_id< T >::obj().

◆ has_flag_furn() [4/4]

bool map::has_flag_furn ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 949 of file map.h.

949 {
950 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
951 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn_or_vpart()

bool map::has_flag_furn_or_vpart ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2439 of file map.cpp.

2440{
2441 return has_flag_furn( flag, p ) || has_flag_vpart( flag, p );
2442}
bool has_flag_vpart(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2433

References has_flag_furn(), and has_flag_vpart().

Referenced by find_furnitures_or_vparts_with_flag_in_radius().

◆ has_flag_ter() [1/4]

◆ has_flag_ter() [2/4]

bool map::has_flag_ter ( const std::string &  flag,
point  p 
) const
inline

Definition at line 919 of file map.h.

919 {
920 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
921 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [3/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2423 of file map.cpp.

2424{
2425 return ter( p ).obj().has_flag( flag );
2426}

References map_data_common_t::has_flag(), int_id< T >::obj(), and ter().

◆ has_flag_ter() [4/4]

bool map::has_flag_ter ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 944 of file map.h.

944 {
945 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
946 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter_or_furn() [1/4]

bool map::has_flag_ter_or_furn ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2404 of file map.cpp.

2405{
2406 if( !inbounds( p ) ) {
2407 return false;
2408 }
2409
2410 point l;
2411 submap *const current_submap = get_submap_at( p, l );
2412
2413 return current_submap && //FIXME: can be null during mapgen
2414 ( current_submap->get_ter( l ).obj().has_flag( flag ) ||
2415 current_submap->get_furn( l ).obj().has_flag( flag ) );
2416}

References submap::get_furn(), get_submap_at(), submap::get_ter(), map_data_common_t::has_flag(), inbounds(), and int_id< T >::obj().

Referenced by can_use_bipod(), could_see_items(), fill_funnels(), inventory::form_from_map(), ranged::gunmode_checks_weapon(), has_flag(), has_flag_ter_or_furn(), has_nearby_fire(), Character::is_deaf(), game::place_player(), vehicle_movement::scan_rails_from_veh_internal(), spawn_monsters_submap_group(), and game::walk_move().

◆ has_flag_ter_or_furn() [2/4]

bool map::has_flag_ter_or_furn ( const std::string &  flag,
point  p 
) const
inline

Definition at line 933 of file map.h.

933 {
934 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
935 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [3/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2444 of file map.cpp.

2445{
2446 if( !inbounds( p ) ) {
2447 return false;
2448 }
2449
2450 point l;
2451 submap *const current_submap = get_submap_at( p, l );
2452
2453 return current_submap && //FIXME: can be null during mapgen
2454 ( current_submap->get_ter( l ).obj().has_flag( flag ) ||
2455 current_submap->get_furn( l ).obj().has_flag( flag ) );
2456}

References submap::get_furn(), get_submap_at(), submap::get_ter(), map_data_common_t::has_flag(), inbounds(), and int_id< T >::obj().

◆ has_flag_ter_or_furn() [4/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
point  p 
) const
inline

Definition at line 954 of file map.h.

954 {
955 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
956 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_vpart()

bool map::has_flag_vpart ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2433 of file map.cpp.

2434{
2435 const optional_vpart_position vp = veh_at( p );
2436 return static_cast<bool>( vp.part_with_feature( flag, true ) );
2437}

References optional_vpart_position::part_with_feature(), and veh_at().

Referenced by has_flag_furn_or_vpart().

◆ has_floor()

bool map::has_floor ( const tripoint p) const

Definition at line 2072 of file map.cpp.

2073{
2074 if( !zlevels || p.z < -OVERMAP_DEPTH + 1 || p.z > OVERMAP_HEIGHT ) {
2075 return true;
2076 }
2077
2078 if( !inbounds( p ) ) {
2079 return true;
2080 }
2081
2082 return get_cache_ref( p.z ).floor_cache[p.x][p.y];
2083}

References level_cache::floor_cache, get_cache_ref(), inbounds(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by drop_everything(), drop_furniture(), drop_items(), floor_between(), game::grabbed_furn_move(), game::print_terrain_info(), ranged_target_size(), and spawn_monsters_submap_group().

◆ has_floor_or_support()

bool map::has_floor_or_support ( const tripoint p) const

Definition at line 2121 of file map.cpp.

2122{
2123 const tripoint below( p.xy(), p.z - 1 );
2124 return !valid_move( p, below, false, true );
2125}

References valid_move(), tripoint::xy(), and tripoint::z.

Referenced by game::print_terrain_info(), avatar_action::ramp_move(), reachable_flood_steps(), and game::vertical_move().

◆ has_furn() [1/2]

◆ has_furn() [2/2]

bool map::has_furn ( point  p) const
inline

Definition at line 789 of file map.h.

789 {
790 return has_furn( tripoint( p, abs_sub.z ) );
791 }

References abs_sub, has_furn(), and tripoint::z.

◆ has_graffiti_at()

bool map::has_graffiti_at ( const tripoint p) const

Definition at line 7980 of file map.cpp.

7981{
7982 if( !inbounds( p ) ) {
7983 return false;
7984 }
7985 point l;
7986 submap *const current_submap = get_submap_at( p, l );
7987 return current_submap->has_graffiti( l );
7988}
bool has_graffiti(point p) const
Definition: submap.cpp:119

References get_submap_at(), submap::has_graffiti(), and inbounds().

Referenced by editmap::draw_main_ui_overlay(), game::place_player(), and game::print_graffiti_info().

◆ has_items()

bool map::has_items ( const tripoint p) const

Checks for existence of items.

Faster than i_at(p).empty

Definition at line 4891 of file map.cpp.

4892{
4893 if( !inbounds( p ) ) {
4894 return false;
4895 }
4896
4897 point l;
4898 submap *const current_submap = get_submap_at( p, l );
4899
4900 return !current_submap->get_items( l ).empty();
4901}

References submap::get_items(), get_submap_at(), and inbounds().

Referenced by bash_items(), drop_furniture(), drop_items(), flammable_items_at(), inventory::form_from_map(), generate_lightmap(), game::place_player(), sees_some_items(), and smash_items().

◆ has_nearby_chair()

bool map::has_nearby_chair ( const tripoint p,
int  radius = 1 
)

Check whether a chair or vehicle seat is nearby.

Definition at line 2843 of file map.cpp.

2844{
2845 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2846 const optional_vpart_position vp = veh_at( pt );
2847 if( has_flag( "CAN_SIT", pt ) ) {
2848 return true;
2849 }
2850 if( vp && vp->vehicle().has_part( "SEAT" ) ) {
2851 return true;
2852 }
2853 }
2854 return false;
2855}

References has_flag(), points_in_radius(), and veh_at().

◆ has_nearby_fire()

bool map::has_nearby_fire ( const tripoint p,
int  radius = 1 
)

Definition at line 2816 of file map.cpp.

2817{
2818 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2819 if( get_field( pt, fd_fire ) != nullptr ) {
2820 return true;
2821 }
2822 if( has_flag_ter_or_furn( "USABLE_FIRE", pt ) ) {
2823 return true;
2824 }
2825 }
2826 return false;
2827}

References fd_fire, get_field(), has_flag_ter_or_furn(), and points_in_radius().

Referenced by inventory::form_from_map().

◆ has_nearby_table()

bool map::has_nearby_table ( const tripoint p,
int  radius = 1 
)

Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating.

Definition at line 2829 of file map.cpp.

2830{
2831 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2832 const optional_vpart_position vp = veh_at( p );
2833 if( has_flag( "FLAT_SURF", pt ) ) {
2834 return true;
2835 }
2836 if( vp && ( vp->vehicle().has_part( "KITCHEN" ) || vp->vehicle().has_part( "FLAT_SURF" ) ) ) {
2837 return true;
2838 }
2839 }
2840 return false;
2841}

References has_flag(), points_in_radius(), and veh_at().

◆ has_zlevels()

◆ hit_with_acid()

bool map::hit_with_acid ( const tripoint p)

Definition at line 3928 of file map.cpp.

3929{
3930 if( passable( p ) ) {
3931 return false; // Didn't hit the tile!
3932 }
3933 const ter_id t = ter( p );
3934 if( t == t_wall_glass || t == t_wall_glass_alarm ||
3935 t == t_vat ) {
3936 ter_set( p, t_floor );
3937 } else if( t == t_door_c || t == t_door_locked || t == t_door_locked_peep ||
3938 t == t_door_locked_alarm ) {
3939 if( one_in( 3 ) ) {
3940 ter_set( p, t_door_b );
3941 }
3942 } else if( t == t_door_bar_c || t == t_door_bar_o || t == t_door_bar_locked || t == t_bars ||
3943 t == t_reb_cage ) {
3944 ter_set( p, t_floor );
3945 add_msg( m_warning, _( "The metal bars melt!" ) );
3946 } else if( t == t_door_b ) {
3947 if( one_in( 4 ) ) {
3948 ter_set( p, t_door_frame );
3949 } else {
3950 return false;
3951 }
3952 } else if( t == t_window || t == t_window_alarm || t == t_window_no_curtains ) {
3953 ter_set( p, t_window_empty );
3954 } else if( t == t_wax ) {
3955 ter_set( p, t_floor_wax );
3956 } else if( t == t_gas_pump || t == t_gas_pump_smashed ) {
3957 return false;
3958 } else if( t == t_card_science || t == t_card_military || t == t_card_industrial ) {
3960 }
3961 return true;
3962}
@ m_warning
Definition: enums.h:264
ter_id t_card_industrial
Definition: mapdata.cpp:725
ter_id t_floor_wax
Definition: mapdata.cpp:688
ter_id t_reb_cage
Definition: mapdata.cpp:657
ter_id t_card_military
Definition: mapdata.cpp:725
ter_id t_door_bar_locked
Definition: mapdata.cpp:666
ter_id t_window_alarm
Definition: mapdata.cpp:671
ter_id t_door_bar_o
Definition: mapdata.cpp:666
ter_id t_gas_pump
Definition: mapdata.cpp:701
ter_id t_wall_glass_alarm
Definition: mapdata.cpp:652
ter_id t_card_reader_broken
Definition: mapdata.cpp:725
ter_id t_gas_pump_smashed
Definition: mapdata.cpp:701
ter_id t_door_locked_peep
Definition: mapdata.cpp:660
ter_id t_door_bar_c
Definition: mapdata.cpp:666
ter_id t_door_frame
Definition: mapdata.cpp:661
ter_id t_vat
Definition: mapdata.cpp:713
ter_id t_window_no_curtains
Definition: mapdata.cpp:675
ter_id t_wax
Definition: mapdata.cpp:688
ter_id t_window_empty
Definition: mapdata.cpp:671
ter_id t_door_b
Definition: mapdata.cpp:659

References _, add_msg(), m_warning, one_in(), passable(), t_bars, t_card_industrial, t_card_military, t_card_reader_broken, t_card_science, t_door_b, t_door_bar_c, t_door_bar_locked, t_door_bar_o, t_door_c, t_door_frame, t_door_locked, t_door_locked_alarm, t_door_locked_peep, t_floor, t_floor_wax, t_gas_pump, t_gas_pump_smashed, t_reb_cage, t_vat, t_wall_glass, t_wall_glass_alarm, t_wax, t_window, t_window_alarm, t_window_empty, t_window_no_curtains, ter(), and ter_set().

◆ hit_with_fire()

bool map::hit_with_fire ( const tripoint p)

Definition at line 3965 of file map.cpp.

3966{
3967 if( passable( p ) ) {
3968 return false; // Didn't hit the tile!
3969 }
3970
3971 // non passable but flammable terrain, set it on fire
3972 if( has_flag( "FLAMMABLE", p ) || has_flag( "FLAMMABLE_ASH", p ) ) {
3973 add_field( p, fd_fire, 3 );
3974 }
3975 return true;
3976}

References add_field(), fd_fire, has_flag(), and passable().

◆ hoist_submap_camp()

basecamp map::hoist_submap_camp ( const tripoint p)

Definition at line 5713 of file map.cpp.

5714{
5715 basecamp *pcamp = get_submap_at( p )->camp.get();
5716 return pcamp ? *pcamp : basecamp();
5717}
std::unique_ptr< basecamp > camp
Definition: submap.h:220

References submap::camp, and get_submap_at().

Referenced by game::validate_camps().

◆ i_at() [1/2]

map_stack map::i_at ( const tripoint p)

Definition at line 4210 of file map.cpp.

4211{
4212 if( !inbounds( p ) ) {
4213 nulitems.clear();
4214 return map_stack{ &nulitems, p, this };
4215 }
4216
4217 point l;
4218 submap *const current_submap = get_submap_at( p, l );
4219
4220 return map_stack{ &current_submap->get_items( l ), p, this };
4221}
static cata::colony< item > nulitems
Definition: map.cpp:142

References submap::get_items(), get_submap_at(), inbounds(), and nulitems.

Referenced by add_item_or_charges(), advanced_inventory_pane::add_items_from_area(), apply_faction_ownership(), bash_furn_success(), bash_items(), board_up(), MapExtras::burned_ground_parser(), game::butcher(), can_butcher_at(), advanced_inventory::change_square(), doors::close_door(), iuse::directional_antenna(), drop_furniture(), drop_items(), editmap::edit_itm(), game::examine(), farm_action(), talk_function::field_harvest(), fill_funnels(), game::find_nearby_items(), flammable_items_at(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), free_volume(), furnname(), generate_lightmap(), advanced_inv_area::get_item_count(), game::grabbed_furn_move(), grow_plant(), liquid_handler::handle_liquid_from_ground(), i_at(), i_rem(), advanced_inventory_pane::load_settings(), talk_function::loot_building(), max_volume(), mop_spills(), MapExtras::mx_supplydrop(), om_harvest_itm(), npc::pick_up_item_map(), game::place_player(), game::print_items_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), serialize_liquid_source(), smash_items(), fungal_effects::spread_fungus_one_tile(), game::start_hauling(), basecamp::start_relay_hide_site(), stored_volume(), tinder_at(), iexamine::toilet(), enzlave_actor::use(), use_amount_square(), use_charges(), use_charges_from_furn(), iexamine::use_furn_fake_item(), and iexamine::vending().

◆ i_at() [2/2]

map_stack map::i_at ( point  p)
inline

Definition at line 1182 of file map.h.

1182 {
1183 return i_at( tripoint( p, abs_sub.z ) );
1184 }

References abs_sub, i_at(), and tripoint::z.

◆ i_clear() [1/2]

void map::i_clear ( const tripoint p)

Definition at line 4248 of file map.cpp.

4249{
4250 point l;
4251 submap *const current_submap = get_submap_at( p, l );
4252
4253 for( item &it : current_submap->get_items( l ) ) {
4254 // remove from the active items cache (if it isn't there does nothing)
4255 current_submap->active_items.remove( &it );
4256 }
4257 if( current_submap->active_items.empty() ) {
4258 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4259 }
4260
4261 current_submap->set_lum( l, 0 );
4262 current_submap->get_items( l ).clear();
4263}
void remove(const item *it)
Removes the item if it is in the cache.
void set_lum(point p, uint8_t luminance)
Definition: submap.h:125

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submap::set_lum(), submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by jmapgen_terrain::apply(), board_up(), doors::close_door(), MapExtras::dead_vegetation_parser(), draw_lab(), drop_furniture(), drop_items(), farm_action(), talk_function::field_harvest(), game::grabbed_furn_move(), grow_plant(), i_clear(), mapgen_lake_shore(), om_harvest_itm(), and rad_scorch().

◆ i_clear() [2/2]

void map::i_clear ( point  p)
inline

Definition at line 1187 of file map.h.

1187 {
1188 i_clear( tripoint( p, abs_sub.z ) );
1189 }

References abs_sub, i_clear(), and tripoint::z.

◆ i_rem() [1/4]

void map::i_rem ( const tripoint p,
item it 
)

Definition at line 4239 of file map.cpp.

4240{
4241 map_stack map_items = i_at( p );
4243 if( iter != map_items.end() ) {
4244 i_rem( p, iter );
4245 }
4246}
iterator get_iterator_from_pointer(item *it)
Definition: item_stack.cpp:68
map_stack::iterator i_rem(const tripoint &p, map_stack::const_iterator it)
Definition: map.cpp:4223

References item_stack::end(), item_stack::get_iterator_from_pointer(), i_at(), and i_rem().

◆ i_rem() [2/4]

map_stack::iterator map::i_rem ( const tripoint p,
map_stack::const_iterator  it 
)

Definition at line 4223 of file map.cpp.

4224{
4225 point l;
4226 submap *const current_submap = get_submap_at( p, l );
4227
4228 // remove from the active items cache (if it isn't there does nothing)
4229 current_submap->active_items.remove( &*it );
4230 if( current_submap->active_items.empty() ) {
4231 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4232 }
4233
4234 current_submap->update_lum_rem( l, *it );
4235
4236 return current_submap->get_items( l ).erase( it );
4237}
void update_lum_rem(point p, const item &i)
Definition: submap.cpp:57

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submaps_with_active_items, submap::update_lum_rem(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by delete_cyborg_item(), map_stack::erase(), i_rem(), om_set_hide_site(), remove_rotten_items(), and smash_items().

◆ i_rem() [3/4]

map_stack::iterator map::i_rem ( point  location,
map_stack::const_iterator  it 
)
inline

Definition at line 1193 of file map.h.

1193 {
1194 return i_rem( tripoint( location, abs_sub.z ), it );
1195 }

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [4/4]

void map::i_rem ( point  p,
item it 
)
inline

Definition at line 1197 of file map.h.

1197 {
1198 i_rem( tripoint( p, abs_sub.z ), it );
1199 }

References abs_sub, i_rem(), and tripoint::z.

◆ impassable() [1/2]

◆ impassable() [2/2]

bool map::impassable ( point  p) const
inline

Definition at line 566 of file map.h.

566 {
567 return !passable( p );
568 }

References passable().

◆ impassable_ter_furn()

bool map::impassable_ter_furn ( const tripoint p) const

Definition at line 1893 of file map.cpp.

1894{
1895 return !passable_ter_furn( p );
1896}
bool passable_ter_furn(const tripoint &p) const
Definition: map.cpp:1898

References passable_ter_furn().

Referenced by climb_difficulty(), and displace_water().

◆ inbounds() [1/3]

bool map::inbounds ( const tripoint p) const
virtual

Reimplemented in tinymap.

Definition at line 7903 of file map.cpp.

7904{
7905 static constexpr tripoint map_boundary_min( 0, 0, -OVERMAP_DEPTH );
7906 static constexpr tripoint map_boundary_max( MAPSIZE_Y, MAPSIZE_X, OVERMAP_HEIGHT + 1 );
7907
7908 static constexpr half_open_cuboid<tripoint> map_boundaries(
7909 map_boundary_min, map_boundary_max );
7910
7911 return map_boundaries.contains( p );
7912}

References half_open_cuboid< Tripoint, >::contains(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by add_field(), add_item(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), add_vehicle(), add_vehicle_to_cache(), adjust_radiation(), ambient_light_at(), grid_furn_transform_queue::apply(), apply_light_source(), apply_vision_transparency_cache(), bash(), bash_rating(), build_sunlight_cache(), clear_path(), clear_vehicle_cache(), clear_vehicle_point_from_cache(), computer_at(), delete_graffiti(), delete_signage(), displace_vehicle(), do_vehicle_caching(), draw(), game::draw_look_around_cursor(), drawsq(), field_at(), furn(), furn_set(), generate_lightmap(), get_field(), get_known_connections(), get_radiation(), get_signage(), get_submap_at(), get_temperature(), graffiti_at(), has_field_at(), has_flag_ter_or_furn(), has_floor(), has_graffiti_at(), has_items(), i_at(), inbounds(), is_bashable(), is_outside(), light_at(), game::load_npcs(), maptile_at(), map_stack::max_volume(), move_cost(), move_cost_ter_furn(), obscured_by_vehicle_rotation(), obstructed_by_vehicle_rotation(), partial_con_at(), partial_con_remove(), partial_con_set(), pl_line_of_sight(), pl_sees(), game::print_all_tile_info(), remove_field(), remove_trap(), restore_vision_transparency_cache(), route(), npc::saw_player_recently(), sees(), set_graffiti(), set_radiation(), set_seen_cache_dirty(), set_signage(), set_temperature(), set_transparency_cache_dirty(), game::shift_monsters(), shift_traps(), shoot(), spawn_items(), ter(), ter_set(), tr_at(), trap_set(), update_suspension_cache(), valid_move(), and veh_at().

◆ inbounds() [2/3]

bool map::inbounds ( const tripoint_abs_ms p) const

Definition at line 7898 of file map.cpp.

7899{
7900 return inbounds( getlocal( p ) );
7901}

References getlocal(), and inbounds().

◆ inbounds() [3/3]

bool map::inbounds ( point  p) const
inline

Definition at line 1624 of file map.h.

1624 {
1625 return inbounds( tripoint( p, 0 ) );
1626 }

References inbounds().

◆ inbounds_z()

◆ invalidate_map_cache()

◆ invalidate_max_populated_zlev()

void map::invalidate_max_populated_zlev ( int  zlev)
private

Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value.

Parameters
zlevzlevel where uniformity change occured

Definition at line 9176 of file map.cpp.

9177{
9178 if( max_populated_zlev && max_populated_zlev->second < zlev ) {
9179 max_populated_zlev->second = zlev;
9180 }
9181}

References max_populated_zlev.

Referenced by add_field(), add_item(), add_vehicle(), displace_vehicle(), furn_set(), shift_vehicle_z(), and ter_set().

◆ is_bashable() [1/2]

bool map::is_bashable ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.

Definition at line 2507 of file map.cpp.

2508{
2509 if( !inbounds( p ) ) {
2510 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2511 return false;
2512 }
2513
2514 if( veh_at( p ).obstacle_at_part() ) {
2515 return true;
2516 }
2517
2518 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2519 return true;
2520 }
2521
2522 const auto &ter_bash = ter( p ).obj().bash;
2523 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2524}

References bash(), map_data_common_t::bash, dbg, furn(), has_furn(), inbounds(), int_id< T >::obj(), map_bash_info::str_max, ter(), veh_at(), and Warn.

Referenced by MapExtras::burned_ground_parser(), features(), game::fling_creature(), is_bashable(), and MapExtras::mx_helicopter().

◆ is_bashable() [2/2]

bool map::is_bashable ( point  p) const
inline

Definition at line 961 of file map.h.

961 {
962 return is_bashable( tripoint( p, abs_sub.z ) );
963 }

References abs_sub, is_bashable(), and tripoint::z.

◆ is_bashable_furn() [1/2]

bool map::is_bashable_furn ( const tripoint p) const

Returns true if the furniture at p is bashable.

Definition at line 2533 of file map.cpp.

2534{
2535 return has_furn( p ) && furn( p ).obj().bash.str_max != -1;
2536}

References map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), and map_bash_info::str_max.

Referenced by is_bashable_furn(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_furn() [2/2]

bool map::is_bashable_furn ( point  p) const
inline

Definition at line 971 of file map.h.

971 {
972 return is_bashable_furn( tripoint( p, abs_sub.z ) );
973 }
bool is_bashable_furn(const tripoint &p) const
Returns true if the furniture at p is bashable.
Definition: map.cpp:2533

References abs_sub, is_bashable_furn(), and tripoint::z.

◆ is_bashable_ter() [1/2]

bool map::is_bashable_ter ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the terrain at p is bashable.

Definition at line 2526 of file map.cpp.

2527{
2528 const auto &ter_bash = ter( p ).obj().bash;
2529 return ter_bash.str_max != -1 && ( ( !ter_bash.bash_below &&
2530 !ter( p ).obj().has_flag( "VEH_TREAT_AS_BASH_BELOW" ) ) || allow_floor );
2531}

References map_data_common_t::bash, map_data_common_t::has_flag(), int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by is_bashable_ter(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter() [2/2]

bool map::is_bashable_ter ( point  p) const
inline

Definition at line 966 of file map.h.

966 {
967 return is_bashable_ter( tripoint( p, abs_sub.z ) );
968 }
bool is_bashable_ter(const tripoint &p, bool allow_floor=false) const
Returns true if the terrain at p is bashable.
Definition: map.cpp:2526

References abs_sub, is_bashable_ter(), and tripoint::z.

◆ is_bashable_ter_furn() [1/2]

bool map::is_bashable_ter_furn ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the furniture or terrain at p is bashable.

Definition at line 2538 of file map.cpp.

2539{
2540 return is_bashable_furn( p ) || is_bashable_ter( p, allow_floor );
2541}

References is_bashable_furn(), and is_bashable_ter().

Referenced by is_bashable_ter_furn().

◆ is_bashable_ter_furn() [2/2]

bool map::is_bashable_ter_furn ( point  p) const
inline

Definition at line 976 of file map.h.

976 {
977 return is_bashable_ter_furn( tripoint( p, abs_sub.z ) );
978 }
bool is_bashable_ter_furn(const tripoint &p, bool allow_floor=false) const
Returns true if the furniture or terrain at p is bashable.
Definition: map.cpp:2538

References abs_sub, is_bashable_ter_furn(), and tripoint::z.

◆ is_cornerfloor()

bool map::is_cornerfloor ( const tripoint p) const

Definition at line 9113 of file map.cpp.

9114{
9115 if( impassable( p ) ) {
9116 return false;
9117 }
9118 std::set<tripoint> impassable_adjacent;
9119 for( const tripoint &pt : points_in_radius( p, 1 ) ) {
9120 if( impassable( pt ) ) {
9121 impassable_adjacent.insert( pt );
9122 }
9123 }
9124 if( !impassable_adjacent.empty() ) {
9125 //to check if a floor is a corner we first search if any of its diagonal adjacent points is impassable
9126 std::set< tripoint> diagonals = { p + tripoint_north_east, p + tripoint_north_west, p + tripoint_south_east, p + tripoint_south_west };
9127 for( const tripoint &impassable_diagonal : diagonals ) {
9128 if( impassable_adjacent.count( impassable_diagonal ) != 0 ) {
9129 //for every impassable diagonal found, we check if that diagonal terrain has at least two impassable neighbors that also neighbor point p
9130 int f = 0;
9131 for( const tripoint &l : points_in_radius( impassable_diagonal, 1 ) ) {
9132 if( impassable_adjacent.count( l ) != 0 ) {
9133 f++;
9134 }
9135 if( f > 2 ) {
9136 return true;
9137 }
9138 }
9139 }
9140 }
9141 }
9142 return false;
9143}
static constexpr tripoint tripoint_north_east
Definition: point.h:272
static constexpr tripoint tripoint_north_west
Definition: point.h:278
static constexpr tripoint tripoint_south_east
Definition: point.h:274
static constexpr tripoint tripoint_south_west
Definition: point.h:276

References impassable(), points_in_radius(), tripoint_north_east, tripoint_north_west, tripoint_south_east, and tripoint_south_west.

◆ is_divable() [1/2]

bool map::is_divable ( const tripoint p) const

Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing).

Parameters
pThe coordinate to look at.
Returns
true if the terrain can be dived into; false if not.

Definition at line 2621 of file map.cpp.

2622{
2623 return has_flag( "SWIMMABLE", p ) && has_flag( TFLAG_DEEP_WATER, p );
2624}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by enchantment::is_active(), and is_divable().

◆ is_divable() [2/2]

bool map::is_divable ( point  p) const
inline

Definition at line 1019 of file map.h.

1019 {
1020 return is_divable( tripoint( p, abs_sub.z ) );
1021 }
bool is_divable(const tripoint &p) const
Returns whether or not the terrain at the given location can be dived into (by monsters that can swim...
Definition: map.cpp:2621

References abs_sub, is_divable(), and tripoint::z.

◆ is_flammable()

bool map::is_flammable ( const tripoint p)

Returns true if there is a flammable item or field or the furn/terrain is flammable at p.

Definition at line 2705 of file map.cpp.

2706{
2707 if( flammable_items_at( p ) ) {
2708 return true;
2709 }
2710
2711 if( has_flag( "FLAMMABLE", p ) ) {
2712 return true;
2713 }
2714
2715 if( has_flag( "FLAMMABLE_ASH", p ) ) {
2716 return true;
2717 }
2718
2719 if( get_field_intensity( p, fd_web ) > 0 ) {
2720 return true;
2721 }
2722
2723 return false;
2724}
int get_field_intensity(const tripoint &p, const field_type_id &type) const
Get the intensity of a field entry (field_entry::intensity), if there is no field of that type,...
Definition: map.cpp:5500
bool flammable_items_at(const tripoint &p, int threshold=0)
Checks if there are any flammable items on the tile.
Definition: map.cpp:2688

References fd_web, flammable_items_at(), get_field_intensity(), and has_flag().

◆ is_harvestable()

bool map::is_harvestable ( const tripoint pos) const

Returns true if point at pos is harvestable right now, with no extra tools.

Definition at line 1695 of file map.cpp.

1696{
1697 const auto &harvest_here = get_harvest( pos );
1698 return !harvest_here.is_null() && !harvest_here->empty();
1699}
const harvest_id & get_harvest(const tripoint &p) const
Returns the full harvest list, for spawning.
Definition: map.cpp:1629

References get_harvest(), and wrapped_vehicle::pos.

◆ is_last_ter_wall()

bool map::is_last_ter_wall ( bool  no_furn,
point  p,
point  max,
direction  dir 
) const

Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST.

Parameters
no_furnif true, the function will stop and return false if it encounters a furniture
pstarting coordinates of check
maxending coordinates of check
dirDirection of check
Returns
true if from x to xmax or y to ymax depending on direction all terrain is floor and the last terrain is a wall

Definition at line 2636 of file map.cpp.

2638{
2639 point mov;
2640 switch( dir ) {
2641 case direction::NORTH:
2642 mov.y = -1;
2643 break;
2644 case direction::SOUTH:
2645 mov.y = 1;
2646 break;
2647 case direction::WEST:
2648 mov.x = -1;
2649 break;
2650 case direction::EAST:
2651 mov.x = 1;
2652 break;
2653 default:
2654 break;
2655 }
2656 point p2( p );
2657 bool result = true;
2658 bool loop = true;
2659 while( ( loop ) && ( ( dir == direction::NORTH && p2.y >= 0 ) ||
2660 ( dir == direction::SOUTH && p2.y < max.y ) ||
2661 ( dir == direction::WEST && p2.x >= 0 ) ||
2662 ( dir == direction::EAST && p2.x < max.x ) ) ) {
2663 if( no_furn && has_furn( p2 ) ) {
2664 loop = false;
2665 result = false;
2666 } else if( !has_flag_ter( "FLAT", p2 ) ) {
2667 loop = false;
2668 if( !has_flag_ter( "WALL", p2 ) ) {
2669 result = false;
2670 }
2671 }
2672 p2.x += mov.x;
2673 p2.y += mov.y;
2674 }
2675 return result;
2676}

References EAST, has_flag_ter(), has_furn(), NORTH, SOUTH, WEST, point::x, and point::y.

Referenced by find_potential_computer_point().

◆ is_outside() [1/2]

◆ is_outside() [2/2]

bool map::is_outside ( point  p) const
inline

Definition at line 1009 of file map.h.

1009 {
1010 return is_outside( tripoint( p, abs_sub.z ) );
1011 }
bool is_outside(const tripoint &p) const
Definition: map.cpp:2626

References abs_sub, is_outside(), and tripoint::z.

◆ is_suspension_valid()

bool map::is_suspension_valid ( const tripoint point)

Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid.

Definition at line 3025 of file map.cpp.

3026{
3027 if( ter( point + tripoint_east ) != t_open_air
3028 && ter( point + tripoint_west ) != t_open_air ) {
3029 return true;
3030 }
3033 return true;
3034 }
3036 && ter( point + tripoint_north ) != t_open_air ) {
3037 return true;
3038 }
3041 return true;
3042 }
3043 return false;
3044}
static constexpr tripoint tripoint_north
Definition: point.h:271
static constexpr tripoint tripoint_west
Definition: point.h:277
static constexpr tripoint tripoint_east
Definition: point.h:273
static constexpr tripoint tripoint_south
Definition: point.h:275

References t_open_air, ter(), tripoint_east, tripoint_north, tripoint_north_east, tripoint_north_west, tripoint_south, tripoint_south_east, tripoint_south_west, and tripoint_west.

Referenced by collapse_invalid_suspension(), and update_suspension_cache().

◆ is_transparent()

bool map::is_transparent ( const tripoint p) const

Returns whether the tile at p is transparent(you can look past it).

Definition at line 691 of file lightmap.cpp.

692{
694}

References light_transparency(), and LIGHT_TRANSPARENCY_SOLID.

Referenced by get_known_connections(), and shoot().

◆ is_wall_adjacent()

bool map::is_wall_adjacent ( const tripoint center) const

Definition at line 1833 of file map.cpp.

1834{
1835 for( const tripoint &p : points_in_radius( center, 1 ) ) {
1836 if( p != center && impassable( p ) ) {
1837 return true;
1838 }
1839 }
1840 return false;
1841}

References center, impassable(), and points_in_radius().

Referenced by ma_requirements::is_valid_character().

◆ is_water_shallow_current() [1/2]

bool map::is_water_shallow_current ( const tripoint p) const

Definition at line 2616 of file map.cpp.

2617{
2618 return has_flag( "CURRENT", p ) && !has_flag( TFLAG_DEEP_WATER, p );
2619}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by is_water_shallow_current().

◆ is_water_shallow_current() [2/2]

bool map::is_water_shallow_current ( point  p) const
inline

Definition at line 1023 of file map.h.

1023 {
1025 }
bool is_water_shallow_current(const tripoint &p) const
Definition: map.cpp:2616

References abs_sub, is_water_shallow_current(), and tripoint::z.

◆ light_at()

lit_level map::light_at ( const tripoint p) const

Definition at line 657 of file lightmap.cpp.

658{
659 if( !inbounds( p ) ) {
660 return lit_level::DARK; // Out of bounds
661 }
662
663 const auto &map_cache = get_cache_ref( p.z );
664 const auto &lm = map_cache.lm;
665 const auto &sm = map_cache.sm;
666 if( sm[p.x][p.y] >= LIGHT_SOURCE_BRIGHT ) {
667 return lit_level::BRIGHT;
668 }
669
670 const float max_light = lm[p.x][p.y].max();
671 if( max_light >= LIGHT_AMBIENT_LIT ) {
672 return lit_level::LIT;
673 }
674
675 if( max_light >= LIGHT_AMBIENT_LOW ) {
676 return lit_level::LOW;
677 }
678
679 return lit_level::DARK;
680}

References BRIGHT, DARK, get_cache_ref(), inbounds(), LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIT, LOW, coords::sm, tripoint::x, tripoint::y, and tripoint::z.

◆ light_transparency()

float map::light_transparency ( const tripoint p) const

Definition at line 696 of file lightmap.cpp.

697{
698 return get_cache_ref( p.z ).transparency_cache[p.x][p.y];
699}

References get_cache_ref(), level_cache::transparency_cache, tripoint::x, tripoint::y, and tripoint::z.

Referenced by generate_lightmap(), and is_transparent().

◆ load() [1/2]

void map::load ( const tripoint w,
bool  update_vehicles,
bool  pump_events = false 
)

Load submaps into grid.

This might create new submaps if the mapbuffer can not deliver the requested submap (as it does not exist on disc). This must be called before the map can be used at all!

Parameters
wglobal coordinates of the submap at grid[0]. This is in submap coordinates.
update_vehiclesIf true, add vehicles to the vehicle cache.
pump_eventsIf true, handle window events during loading. If you set this to true, do ensure that the map is not accessed before this function returns (for example, UIs that draw the map should be disabled).

Definition at line 6750 of file map.cpp.

6751{
6752 for( auto &traps : traplocs ) {
6753 traps.clear();
6754 }
6755 field_furn_locs.clear();
6757 set_abs_sub( w );
6758 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6759 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6760 loadn( point( gridx, gridy ), update_vehicle );
6761 if( pump_events ) {
6763 }
6764 }
6765 }
6767}
void pump_events()
Resize & refresh if necessary, process all pending window events, and ignore keypresses.
void loadn(const tripoint &grid, bool update_vehicles)
Definition: map.cpp:7132
input_manager inp_mngr
Definition: input.cpp:109

References field_furn_locs, inp_mngr, loadn(), my_MAPSIZE, input_manager::pump_events(), reset_vehicle_cache(), set_abs_sub(), submaps_with_active_items, and traplocs.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), debug_menu::debug(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), find_valid_teleporters_omt(), basecamp::form_crafting_inventory(), mission_start::kill_horde_master(), load(), game::load_map(), talk_function::loot_building(), editmap::mapgen_veh_destroy(), editmap::mapgen_veh_query(), MapExtras::mx_minefield(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), teleporter_list::place_avatar_overmap(), Character::place_corpse(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), debug_menu::spawn_nested_mapgen(), basecamp::start_relay_hide_site(), update_mapgen_function_json::update_map(), game::vertical_move(), and game::vertical_shift().

◆ load() [2/2]

void map::load ( const tripoint_abs_sm w,
bool  update_vehicles,
bool  pump_events = false 
)

Definition at line 6769 of file map.cpp.

6770{
6771 // TODO: fix point types
6772 load( w.raw(), update_vehicle, pump_events );
6773}
void load(const tripoint &w, bool update_vehicles, bool pump_events=false)
Load submaps into grid.
Definition: map.cpp:6750

References load(), and coords::coord_point< Point, Origin, Scale >::raw().

◆ loadn() [1/2]

void map::loadn ( const tripoint grid,
bool  update_vehicles 
)
protected

Definition at line 7132 of file map.cpp.

7133{
7134 // Cache empty overmap types
7135 static const oter_id rock( "empty_rock" );
7136 static const oter_id air( "open_air" );
7137
7138 const tripoint grid_abs_sub = abs_sub.xy() + grid;
7139 const size_t gridn = get_nonant( grid );
7140
7141 const int old_abs_z = abs_sub.z; // Ugly, but necessary at the moment
7142 abs_sub.z = grid.z;
7143
7144 submap *tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7145 if( tmpsub == nullptr ) {
7146 // It doesn't exist; we must generate it!
7147 dbg( DL::Info ) << "map::loadn: Missing mapbuffer data. Regenerating.";
7148
7149 // Each overmap square is two nonants; to prevent overlap, generate only at
7150 // squares divisible by 2.
7151 // TODO: fix point types
7152 const tripoint_abs_omt grid_abs_omt( sm_to_omt_copy( grid_abs_sub ) );
7153 const tripoint grid_abs_sub_rounded = omt_to_sm_copy( grid_abs_omt.raw() );
7154
7155 const oter_id terrain_type = overmap_buffer.ter( grid_abs_omt );
7156
7157 // Short-circuit if the map tile is uniform
7158 // TODO: Replace with json mapgen functions.
7159 if( terrain_type == air ) {
7160 generate_uniform( grid_abs_sub_rounded, t_open_air );
7161 } else if( terrain_type == rock ) {
7162 generate_uniform( grid_abs_sub_rounded, t_rock );
7163 } else {
7164 tinymap tmp_map;
7165 tmp_map.generate( grid_abs_sub_rounded, calendar::turn );
7166 }
7167
7168 // This is the same call to MAPBUFFER as above!
7169 tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
7170 if( tmpsub == nullptr ) {
7171 debugmsg( "failed to generate a submap at %s", grid_abs_sub.to_string() );
7172 return;
7173 }
7174 }
7175
7176 // New submap changes the content of the map and all caches must be recalculated
7183 setsubmap( gridn, tmpsub );
7184 if( !tmpsub->active_items.empty() ) {
7185 submaps_with_active_items.emplace( grid_abs_sub );
7186 }
7187 if( tmpsub->field_count > 0 ) {
7188 get_cache( grid.z ).field_cache.set( grid.x + grid.y * MAPSIZE );
7189 }
7190 // Destroy bugged no-part vehicles
7191 auto &veh_vec = tmpsub->vehicles;
7192 for( auto iter = veh_vec.begin(); iter != veh_vec.end(); ) {
7193 vehicle *veh = iter->get();
7194 if( veh->part_count() > 0 ) {
7195 // Always fix submap coordinates for easier Z-level-related operations
7196 veh->sm_pos = grid;
7197 veh->attach();
7198 iter++;
7199 } else {
7201 if( veh->tracking_on ) {
7203 }
7204 dirty_vehicle_list.erase( veh );
7205 iter = veh_vec.erase( iter );
7206 }
7207 }
7208
7209 // Update vehicle data
7210 if( update_vehicles ) {
7211 auto &map_cache = get_cache( grid.z );
7212 for( const auto &veh : tmpsub->vehicles ) {
7213 // Only add if not tracking already.
7214 if( map_cache.vehicle_list.find( veh.get() ) == map_cache.vehicle_list.end() ) {
7215 map_cache.vehicle_list.insert( veh.get() );
7216 if( !veh->loot_zones.empty() ) {
7217 map_cache.zone_vehicles.insert( veh.get() );
7218 }
7219 add_vehicle_to_cache( veh.get() );
7220 }
7221 }
7222 }
7223
7224 actualize( grid );
7225
7226 abs_sub.z = old_abs_z;
7227}
void set_suspension_cache_dirty(const int zlev)
Definition: map.cpp:229
void generate(const tripoint &p, const time_point &when)
Definition: mapgen.cpp:109
void actualize(const tripoint &grid)
Fast forward a submap that has just been loading into this map.
Definition: map.cpp:7547
submap * lookup_submap(const tripoint &p)
Get a submap stored in this buffer.
Definition: mapbuffer.cpp:83
Definition: map.h:2065
std::unordered_multimap< point, zone_data > loot_zones
Definition: vehicle.h:1595
int part_count() const
Definition: vehicle.cpp:7100
void attach()
Definition: vehicle.h:472
point omt_to_sm_copy(point p)
static void generate_uniform(const tripoint &p, const ter_id &terrain_type)
Definition: map.cpp:7116
mapbuffer MAPBUFFER
Definition: mapbuffer.cpp:40

References abs_sub, submap::active_items, actualize(), add_vehicle_to_cache(), vehicle::attach(), dbg, debugmsg, dirty_vehicle_list, active_item_cache::empty(), level_cache::field_cache, submap::field_count, generate(), generate_uniform(), get_cache(), get_nonant(), grid, Info, mapbuffer::lookup_submap(), MAPBUFFER, MAPSIZE, omt_to_sm_copy(), overmap_buffer, vehicle::part_count(), coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), set_transparency_cache_dirty(), setsubmap(), vehicle::sm_pos, sm_to_omt_copy(), submaps_with_active_items, t_open_air, t_rock, overmapbuffer::ter(), tripoint::to_string(), vehicle::tracking_on, calendar::turn, submap::vehicles, tripoint::xy(), and tripoint::z.

Referenced by load(), loadn(), and shift().

◆ loadn() [2/2]

void map::loadn ( point  grid,
bool  update_vehicles 
)
inlineprotected

Definition at line 1678 of file map.h.

1678 {
1679 if( zlevels ) {
1680 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1681 loadn( tripoint( grid, gridz ), update_vehicles );
1682 }
1683
1684 // Note: we want it in a separate loop! It is a post-load cleanup
1685 // Since we're adding roofs, we want it to go up (from lowest to highest)
1686 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1687 add_roofs( tripoint( grid, gridz ) );
1688 }
1689 } else {
1690 loadn( tripoint( grid, abs_sub.z ), update_vehicles );
1691 }
1692 }
void add_roofs(const tripoint &grid)
Hacks in missing roofs.
Definition: map.cpp:7602

References abs_sub, add_roofs(), grid, loadn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

◆ make_active()

void map::make_active ( item_location loc)

Update an item's active status, for example when adding hot or perishable liquid to a container.

Definition at line 4547 of file map.cpp.

4548{
4549 item *target = loc.get_item();
4550
4551 // Trust but verify, don't let stinking callers set items active when they shouldn't be.
4552 if( !target->needs_processing() ) {
4553 return;
4554 }
4555 point l;
4556 submap *const current_submap = get_submap_at( loc.position(), l );
4557 cata::colony<item> &item_stack = current_submap->get_items( l );
4559
4560 if( current_submap->active_items.empty() ) {
4562 abs_sub.y + loc.position().y / SEEY, loc.position().z ) );
4563 }
4564 current_submap->active_items.add( *iter, l );
4565}
item * get_item()
Gets the selected item or nullptr.
tripoint position() const
Returns the position where the item is found.

References abs_sub, submap::active_items, active_item_cache::add(), active_item_cache::empty(), item_location::get_item(), submap::get_items(), item_stack::get_iterator_from_pointer(), get_submap_at(), item::needs_processing(), item_location::position(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

◆ make_rubble() [1/3]

void map::make_rubble ( const tripoint p)
inline

Definition at line 1004 of file map.h.

1004 {
1005 make_rubble( p, f_rubble, t_dirt, false );
1006 }

References f_rubble, make_rubble(), and t_dirt.

◆ make_rubble() [2/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type 
)
inline

Definition at line 1001 of file map.h.

1001 {
1002 make_rubble( p, rubble_type, t_dirt, false );
1003 }

References make_rubble(), and t_dirt.

◆ make_rubble() [3/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
const ter_id floor_type,
bool  overwrite = false 
)

Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true.

Definition at line 2592 of file map.cpp.

2594{
2595 if( overwrite ) {
2596 ter_set( p, floor_type );
2597 furn_set( p, rubble_type );
2598 } else {
2599 // First see if there is existing furniture to destroy
2600 if( is_bashable_furn( p ) ) {
2601 destroy_furn( p, true );
2602 }
2603 // Leave the terrain alone unless it interferes with furniture placement
2604 if( impassable( p ) && is_bashable_ter( p ) ) {
2605 destroy( p, true );
2606 }
2607 // Check again for new terrain after potential destruction
2608 if( impassable( p ) ) {
2609 ter_set( p, floor_type );
2610 }
2611
2612 furn_set( p, rubble_type );
2613 }
2614}
void destroy_furn(const tripoint &p, bool silent=false)
Keeps bashing a square until there is no more furniture.
Definition: map.cpp:3751

References destroy(), destroy_furn(), furn_set(), impassable(), is_bashable_furn(), is_bashable_ter(), and ter_set().

Referenced by jmapgen_make_rubble::apply(), collapse_at(), draw_lab(), draw_mine(), make_rubble(), mapgen_crater(), MapExtras::mx_helicopter(), and MapExtras::mx_portal().

◆ maptile_at() [1/2]

maptile map::maptile_at ( const tripoint p)

Definition at line 270 of file map.cpp.

271{
272 if( !inbounds( p ) ) {
273 return maptile( &null_submap, point_zero );
274 }
275
276 return maptile_at_internal( p );
277}
static submap null_submap
Definition: map.cpp:259

References inbounds(), maptile_at_internal(), null_submap, and point_zero.

◆ maptile_at() [2/2]

maptile map::maptile_at ( const tripoint p) const

Definition at line 261 of file map.cpp.

262{
263 if( !inbounds( p ) ) {
264 return maptile( &null_submap, point_zero );
265 }
266
267 return maptile_at_internal( p );
268}

References inbounds(), maptile_at_internal(), null_submap, and point_zero.

Referenced by editmap::draw_main_ui_overlay(), drawsq(), gas_can_spread_to(), get_wind_blockers(), maptile_has_bounds(), supports_above(), and valid_move().

◆ maptile_at_internal() [1/2]

maptile map::maptile_at_internal ( const tripoint p)
private

Definition at line 287 of file map.cpp.

288{
289 point l;
290 submap *const sm = get_submap_at( p, l );
291
292 return maptile( sm, l );
293}

References get_submap_at(), and coords::sm.

◆ maptile_at_internal() [2/2]

maptile map::maptile_at_internal ( const tripoint p) const
private

Definition at line 279 of file map.cpp.

280{
281 point l;
282 submap *const sm = get_submap_at( p, l );
283
284 return maptile( sm, l );
285}

References get_submap_at(), and coords::sm.

Referenced by draw(), maptile_at(), maptile_has_bounds(), process_fields_in_submap(), route(), and spread_gas().

◆ maptile_has_bounds()

std::pair< tripoint, maptile > map::maptile_has_bounds ( const tripoint p,
bool  bounds_checked 
)
private

Definition at line 181 of file map_field.cpp.

182{
183 if( bounds_checked ) {
184 // We know that the point is in bounds
185 return {p, maptile_at_internal( p )};
186 }
187
188 return {p, maptile_at( p )};
189}

References maptile_at(), and maptile_at_internal().

Referenced by get_neighbors().

◆ max_volume()

units::volume map::max_volume ( const tripoint p)

Definition at line 4338 of file map.cpp.

4339{
4340 return i_at( p ).max_volume();
4341}
units::volume max_volume() const override
Maximum volume allowed here.
Definition: map.cpp:164

References i_at(), and map_stack::max_volume().

Referenced by advanced_inventory::print_items().

◆ mod_field_age()

time_duration map::mod_field_age ( const tripoint p,
const field_type_id type,
const time_duration offset 
)

Increment/decrement age of field entry at point.

Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5449 of file map.cpp.

5451{
5452 return set_field_age( p, type, offset, true );
5453}
time_duration set_field_age(const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
Set age of field entry at point.
Definition: map.cpp:5460

References set_field_age(), and type.

Referenced by game::process_artifact().

◆ mod_field_intensity()

int map::mod_field_intensity ( const tripoint p,
const field_type_id type,
int  offset 
)

Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5455 of file map.cpp.

5456{
5457 return set_field_intensity( p, type, offset, true );
5458}
int set_field_intensity(const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.
Definition: map.cpp:5473

References set_field_intensity(), and type.

Referenced by add_splatter(), and propagate_field().

◆ monster_in_field()

void map::monster_in_field ( monster z)
protected

Definition at line 1632 of file map_field.cpp.

1633{
1634 if( z.digging() ) {
1635 // Digging monsters are immune to fields
1636 return;
1637 }
1638 if( veh_at( z.pos() ) ) {
1639 // FIXME: Immune when in a vehicle for now.
1640 return;
1641 }
1642 field &curfield = get_field( z.pos() );
1643
1644 int dam = 0;
1645 // Iterate through all field effects on this tile.
1646 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1647 // later by the field processing, which will also adjust field_count accordingly.
1648 for( auto &field_list_it : curfield ) {
1649 field_entry &cur = field_list_it.second;
1650 if( !cur.is_field_alive() ) {
1651 continue;
1652 }
1653 const field_type_id cur_field_type = cur.get_field_type();
1654 if( cur_field_type == fd_web ) {
1655 if( !z.has_flag( MF_WEBWALK ) ) {
1656 z.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1657 cur.set_field_intensity( 0 );
1658 }
1659 }
1660 if( cur_field_type == fd_acid ) {
1661 if( !z.flies() ) {
1662 const int d = rng( cur.get_field_intensity(), cur.get_field_intensity() * 3 );
1663 z.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_ACID, d ) );
1664 z.check_dead_state();
1665 if( d > 0 ) {
1666 z.add_effect( effect_corroding, 1_turns * rng( d / 2, d * 2 ) );
1667 }
1668 }
1669
1670 }
1671 if( cur_field_type == fd_sap ) {
1672 z.moves -= cur.get_field_intensity() * 5;
1674 }
1675 if( cur_field_type == fd_sludge ) {
1676 if( !z.digs() && !z.flies() &&
1677 !z.has_flag( MF_SLUDGEPROOF ) ) {
1678 z.moves -= cur.get_field_intensity() * 300;
1679 cur.set_field_intensity( 0 );
1680 }
1681 }
1682 if( cur_field_type == fd_fire ) {
1683 // TODO: MATERIALS Use fire resistance
1684 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1685 return;
1686 }
1687 // TODO: Replace the section below with proper json values
1689 dam += 3;
1690 }
1691 if( z.made_of( material_id( "veggy" ) ) ) {
1692 dam += 12;
1693 }
1695 dam += 20;
1696 }
1698 dam += -20;
1699 }
1700 if( z.flies() ) {
1701 dam -= 15;
1702 }
1703 dam -= z.get_armor_type( DT_HEAT, bodypart_id( "torso" ) );
1704
1705 if( cur.get_field_intensity() == 1 ) {
1706 dam += rng( 2, 6 );
1707 } else if( cur.get_field_intensity() == 2 ) {
1708 dam += rng( 6, 12 );
1709 if( !z.flies() ) {
1710 z.moves -= 20;
1711 if( dam > 0 ) {
1712 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1713 }
1714 }
1715 } else if( cur.get_field_intensity() == 3 ) {
1716 dam += rng( 10, 20 );
1717 if( !z.flies() || one_in( 3 ) ) {
1718 z.moves -= 40;
1719 if( dam > 0 ) {
1720 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1721 }
1722 }
1723 }
1724 }
1725 if( cur_field_type == fd_smoke ) {
1726 if( !z.has_flag( MF_NO_BREATHE ) ) {
1727 if( cur.get_field_intensity() == 3 ) {
1728 z.moves -= rng( 10, 20 );
1729 }
1730 // Plants suffer from smoke even worse
1731 if( z.made_of( material_id( "veggy" ) ) ) {
1732 z.moves -= rng( 1, cur.get_field_intensity() * 12 );
1733 }
1734 }
1735
1736 }
1737 if( cur_field_type == fd_tear_gas ) {
1739 if( cur.get_field_intensity() == 3 ) {
1740 z.add_effect( effect_stunned, rng( 1_minutes, 2_minutes ) );
1741 dam += rng( 4, 10 );
1742 } else if( cur.get_field_intensity() == 2 ) {
1743 z.add_effect( effect_stunned, rng( 5_turns, 10_turns ) );
1744 dam += rng( 2, 5 );
1745 } else {
1746 z.add_effect( effect_stunned, rng( 1_turns, 5_turns ) );
1747 }
1748 if( z.made_of( material_id( "veggy" ) ) ) {
1749 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1750 dam += cur.get_field_intensity() * rng( 8, 14 );
1751 }
1752 if( z.has_flag( MF_SEES ) ) {
1753 z.add_effect( effect_blind, cur.get_field_intensity() * 8_turns );
1754 }
1755 }
1756
1757 }
1758 if( cur_field_type == fd_relax_gas ) {
1760 z.add_effect( effect_stunned, rng( cur.get_field_intensity() * 4_turns,
1761 cur.get_field_intensity() * 8_turns ) );
1762 }
1763 }
1764 if( cur_field_type == fd_dazzling ) {
1765 if( z.has_flag( MF_SEES ) && !z.has_flag( MF_ELECTRONIC ) ) {
1766 z.add_effect( effect_blind, cur.get_field_intensity() * 12_turns );
1767 z.add_effect( effect_stunned, cur.get_field_intensity() * rng( 5_turns, 12_turns ) );
1768 }
1769
1770 }
1771 if( cur_field_type == fd_toxic_gas ) {
1772 if( !z.has_flag( MF_NO_BREATHE ) ) {
1773 dam += cur.get_field_intensity();
1774 z.moves -= cur.get_field_intensity();
1775 }
1776
1777 }
1778 if( cur_field_type == fd_nuke_gas ) {
1779 if( !z.has_flag( MF_NO_BREATHE ) ) {
1780 if( cur.get_field_intensity() == 3 ) {
1781 z.moves -= rng( 60, 120 );
1782 dam += rng( 30, 50 );
1783 } else if( cur.get_field_intensity() == 2 ) {
1784 z.moves -= rng( 20, 50 );
1785 dam += rng( 10, 25 );
1786 } else {
1787 z.moves -= rng( 0, 15 );
1788 dam += rng( 0, 12 );
1789 }
1790 if( z.made_of( material_id( "veggy" ) ) ) {
1791 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1792 dam *= cur.get_field_intensity();
1793 }
1794 }
1795
1796 }
1797 if( cur_field_type == fd_flame_burst ) {
1798 // TODO: MATERIALS Use fire resistance
1799 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1800 return;
1801 }
1803 dam += 3;
1804 }
1805 if( z.made_of( material_id( "veggy" ) ) ) {
1806 dam += 12;
1807 }
1809 dam += 50;
1810 }
1812 dam += -25;
1813 }
1814 dam += rng( 0, 8 );
1815 z.moves -= 20;
1816 }
1817 if( cur_field_type == fd_electricity ) {
1818 // We don't want to increase dam, but deal a separate hit so that it can apply effects
1819 z.deal_damage( nullptr, bodypart_id( "torso" ),
1820 damage_instance( DT_ELECTRIC, rng( 1, cur.get_field_intensity() * 3 ) ) );
1821 }
1822 if( cur_field_type == fd_fatigue ) {
1823 if( rng( 0, 2 ) < cur.get_field_intensity() ) {
1824 dam += cur.get_field_intensity();
1825 teleport::teleport( z );
1826 }
1827 }
1828 if( cur_field_type == fd_incendiary ) {
1829 // TODO: MATERIALS Use fire resistance
1830 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1831 return;
1832 }
1834 dam += 3;
1835 }
1836 if( z.made_of( material_id( "veggy" ) ) ) {
1837 dam += 12;
1838 }
1840 dam += 20;
1841 }
1843 dam += -5;
1844 }
1845
1846 if( cur.get_field_intensity() == 1 ) {
1847 dam += rng( 2, 6 );
1848 } else if( cur.get_field_intensity() == 2 ) {
1849 dam += rng( 6, 12 );
1850 z.moves -= 20;
1851 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1852 z.add_effect( effect_onfire, rng( 8_turns, 12_turns ) );
1853 }
1854 } else if( cur.get_field_intensity() == 3 ) {
1855 dam += rng( 10, 20 );
1856 z.moves -= 40;
1857 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1858 z.add_effect( effect_onfire, rng( 12_turns, 16_turns ) );
1859 }
1860 }
1861 }
1862 if( cur_field_type == fd_fungal_haze ) {
1863 if( !z.type->in_species( FUNGUS ) &&
1864 !z.type->has_flag( MF_NO_BREATHE ) &&
1865 !z.make_fungus() ) {
1866 // Don't insta-kill jabberwocks, that's silly
1867 const int intensity = cur.get_field_intensity();
1868 z.moves -= rng( 10 * intensity, 30 * intensity );
1869 dam += rng( 0, 10 * intensity );
1870 }
1871 }
1872 if( cur_field_type == fd_fungicidal_gas ) {
1873 if( z.type->in_species( FUNGUS ) ) {
1874 const int intensity = cur.get_field_intensity();
1875 z.moves -= rng( 10 * intensity, 30 * intensity );
1876 dam += rng( 4, 7 * intensity );
1877 }
1878 }
1879 if( cur_field_type == fd_insecticidal_gas ) {
1880 if( z.type->in_species( INSECT ) || z.type->in_species( SPIDER ) ) {
1881 const int intensity = cur.get_field_intensity();
1882 z.moves -= rng( 10 * intensity, 30 * intensity );
1883 dam += rng( 4, 7 * intensity );
1884 }
1885 }
1886 }
1887
1888 if( dam > 0 ) {
1889 z.apply_damage( nullptr, bodypart_id( "torso" ), dam, true );
1890 z.check_dead_state();
1891 }
1892}
static const std::set< material_id > cmat_flammable
Definition: creature.h:486
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:902
static const std::set< material_id > cmat_flesh
Definition: creature.h:484
int moves
Definition: creature.h:582
static const std::set< material_id > cmat_fleshnveg
Definition: creature.h:485
static const std::set< material_id > cmat_flameres
Definition: creature.h:487
bool has_flag(m_flag f) const override
Definition: monster.cpp:894
bool digs() const
Definition: monster.cpp:936
bool made_of_any(const std::set< material_id > &ms) const override
Definition: monster.cpp:988
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1862
bool make_fungus()
Makes this monster into a fungus version Returns false if no such monster exists Returns true if mons...
Definition: monster.cpp:2666
const tripoint & pos() const override
Definition: monster.cpp:252
bool made_of(const material_id &m) const override
Definition: monster.cpp:983
const mtype * type
Definition: monster.h:478
int get_armor_type(damage_type dt, bodypart_id bp) const override
Definition: monster.cpp:1923
bool flies() const
Definition: monster.cpp:941
bool digging() const override
Definition: monster.cpp:926
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_HEAT
Definition: damage.h:28
field_type_id fd_incendiary
Definition: field_type.cpp:372
field_type_id fd_toxic_gas
Definition: field_type.cpp:347
field_type_id fd_tear_gas
Definition: field_type.cpp:348
field_type_id fd_sludge
Definition: field_type.cpp:344
field_type_id fd_nuke_gas
Definition: field_type.cpp:349
field_type_id fd_dazzling
Definition: field_type.cpp:361
field_type_id fd_electricity
Definition: field_type.cpp:353
field_type_id fd_fungal_haze
Definition: field_type.cpp:374
field_type_id fd_smoke
Definition: field_type.cpp:346
field_type_id fd_sap
Definition: field_type.cpp:343
field_type_id fd_fungicidal_gas
Definition: field_type.cpp:383
field_type_id fd_acid
Definition: field_type.cpp:342
field_type_id fd_flame_burst
Definition: field_type.cpp:352
field_type_id fd_relax_gas
Definition: field_type.cpp:373
field_type_id fd_fatigue
Definition: field_type.cpp:354
field_type_id fd_insecticidal_gas
Definition: field_type.cpp:384
static const efftype_id effect_blind("blind")
static const species_id FUNGUS("FUNGUS")
static const species_id INSECT("INSECT")
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_stunned("stunned")
static const species_id SPIDER("SPIDER")
static const efftype_id effect_onfire("onfire")
@ MF_SEES
Definition: mtype.h:67
@ MF_FIREY
Definition: mtype.h:103
@ MF_WEBWALK
Definition: mtype.h:85
@ MF_FIREPROOF
Definition: mtype.h:99
@ MF_SLUDGEPROOF
Definition: mtype.h:100
@ MF_ELECTRONIC
Definition: mtype.h:105
@ MF_NO_BREATHE
Definition: mtype.h:123
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
bool has_flag(m_flag flag) const
Definition: mtype.cpp:75
bool in_species(const species_id &spec) const
Definition: mtype.cpp:122

References monster::add_effect(), monster::apply_damage(), Creature::check_dead_state(), Creature::cmat_flameres, Creature::cmat_flammable, Creature::cmat_flesh, Creature::cmat_fleshnveg, Creature::deal_damage(), monster::digging(), monster::digs(), DT_ACID, DT_ELECTRIC, DT_HEAT, effect_blind, effect_corroding, effect_onfire, effect_stunned, effect_webbed, fd_acid, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_nuke_gas, fd_relax_gas, fd_sap, fd_sludge, fd_smoke, fd_tear_gas, fd_toxic_gas, fd_web, monster::flies(), FUNGUS, monster::get_armor_type(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), monster::has_flag(), mtype::has_flag(), mtype::in_species(), INSECT, field_entry::is_field_alive(), LIQUID, monster::made_of(), monster::made_of_any(), monster::make_fungus(), MF_ELECTRONIC, MF_FIREPROOF, MF_FIREY, MF_NO_BREATHE, MF_SEES, MF_SLUDGEPROOF, MF_WEBWALK, Creature::moves, num_bp, one_in(), monster::pos(), rng(), field_entry::set_field_intensity(), SPIDER, teleport::teleport(), monster::type, and veh_at().

Referenced by creature_in_field().

◆ mop_spills()

bool map::mop_spills ( const tripoint p)

Remove moppable fields/items at this location.

Parameters
pthe location
Returns
true if anything moppable was there, false otherwise.

Definition at line 2857 of file map.cpp.

2858{
2859 bool retval = false;
2860
2861 if( !has_flag( "LIQUIDCONT", p ) && !has_flag( "SEALED", p ) ) {
2862 auto items = i_at( p );
2863 auto new_end = std::remove_if( items.begin(), items.end(), []( const item & it ) {
2864 return it.made_of( LIQUID );
2865 } );
2866 retval = new_end != items.end();
2867 while( new_end != items.end() ) {
2868 new_end = items.erase( new_end );
2869 }
2870 }
2871
2872 field &fld = field_at( p );
2873 static const std::vector<field_type_id> to_check = {
2874 fd_blood,
2882 fd_bile,
2883 fd_slime,
2884 fd_sludge
2885 };
2886 for( field_type_id fid : to_check ) {
2887 retval |= fld.remove_field( fid );
2888 }
2889
2890 if( const optional_vpart_position vp = veh_at( p ) ) {
2891 vehicle *const veh = &vp->vehicle();
2892 std::vector<int> parts_here = veh->parts_at_relative( vp->mount(), true );
2893 for( auto &elem : parts_here ) {
2894 if( veh->part( elem ).blood > 0 ) {
2895 veh->part( elem ).blood = 0;
2896 retval = true;
2897 }
2898 //remove any liquids that somehow didn't fall through to the ground
2899 vehicle_stack here = veh->get_items( elem );
2900 auto new_end = std::remove_if( here.begin(), here.end(), []( const item & it ) {
2901 return it.made_of( LIQUID );
2902 } );
2903 retval |= ( new_end != here.end() );
2904 while( new_end != here.end() ) {
2905 new_end = here.erase( new_end );
2906 }
2907 }
2908 } // if veh != 0
2909 return retval;
2910}
bool remove_field(const field_type_id &field_to_remove)
Removes the field entry with a type equal to the field_type_id parameter.
Definition: field.cpp:219
std::vector< int > parts_at_relative(point dp, bool use_cache) const
Definition: vehicle.cpp:2418
field_type_id fd_gibs_insect
Definition: field_type.cpp:365
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_bile
Definition: field_type.cpp:337
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_gibs_veggy
Definition: field_type.cpp:339
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_slime
Definition: field_type.cpp:341
field_type_id fd_gibs_invertebrate
Definition: field_type.cpp:366
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338
auto here(const Character &you) -> elevator::tiles

References vehicle_part::blood, fd_bile, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, fd_gibs_flesh, fd_gibs_insect, fd_gibs_invertebrate, fd_gibs_veggy, fd_slime, fd_sludge, field_at(), vehicle::get_items(), has_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), i_at(), vehicle::part(), vehicle::parts_at_relative(), field::remove_field(), veh_at(), and vehicle::vehicle().

◆ move_cost() [1/2]

int map::move_cost ( const tripoint p,
const vehicle ignored_vehicle = nullptr 
) const

Calculate the cost to move past the tile at p.

The move cost is determined by various obstacles, such as terrain, vehicles and furniture.

Note
Movement costs for players and zombies both use this function.
Returns
The return value is interpreted as follows:
Move Cost Meaning
0 Impassable. Use passable/impassable to check for this.
n > 0 x*n turns to move past this

Definition at line 1845 of file map.cpp.

1846{
1847 if( !inbounds( p ) ) {
1848 return 0;
1849 }
1850
1851 const furn_t &furniture = furn( p ).obj();
1852 const ter_t &terrain = ter( p ).obj();
1853 const optional_vpart_position vp = veh_at( p );
1854 vehicle *const veh = ( !vp || &vp->vehicle() == ignored_vehicle ) ? nullptr : &vp->vehicle();
1855 const int part = veh ? vp->part_index() : -1;
1856
1857 return move_cost_internal( furniture, terrain, veh, part );
1858}
int move_cost_internal(const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
Internal versions of public functions to avoid checking same variables multiple times.
Definition: map.cpp:1808

References furn(), furniture, inbounds(), move_cost_internal(), int_id< T >::obj(), ter(), terrain, and veh_at().

Referenced by combined_movecost(), draw_mine(), move_cost(), obstacle_coverage(), passable(), game::print_terrain_info(), reachable_flood_steps(), game::vertical_move(), and game::walk_move().

◆ move_cost() [2/2]

int map::move_cost ( point  p,
const vehicle ignored_vehicle = nullptr 
) const
inline

Definition at line 562 of file map.h.

562 {
563 return move_cost( tripoint( p, abs_sub.z ), ignored_vehicle );
564 }

References abs_sub, move_cost(), and tripoint::z.

◆ move_cost_internal()

int map::move_cost_internal ( const furn_t furniture,
const ter_t terrain,
const vehicle veh,
int  vpart 
) const
private

Internal versions of public functions to avoid checking same variables multiple times.

They lack safety checks, because their callers already do those.

Definition at line 1808 of file map.cpp.

1810{
1811 if( terrain.movecost == 0 || ( furniture.id && furniture.movecost < 0 ) ) {
1812 return 0;
1813 }
1814
1815 if( veh != nullptr ) {
1816 const vpart_position vp( const_cast<vehicle &>( *veh ), vpart );
1817 if( vp.obstacle_at_part() ) {
1818 return 0;
1819 } else if( vp.part_with_feature( VPFLAG_AISLE, true ) ) {
1820 return 2;
1821 } else {
1822 return 8;
1823 }
1824 }
1825
1826 if( furniture.id ) {
1827 return std::max( terrain.movecost + furniture.movecost, 0 );
1828 }
1829
1830 return std::max( terrain.movecost, 0 );
1831}

References furniture, vpart_position::obstacle_at_part(), vpart_position::part_with_feature(), terrain, and VPFLAG_AISLE.

Referenced by move_cost(), route(), and update_pathfinding_cache().

◆ move_cost_ter_furn() [1/2]

int map::move_cost_ter_furn ( const tripoint p) const

Similar behavior to move_cost(), but ignores vehicles.

Definition at line 1870 of file map.cpp.

1871{
1872 if( !inbounds( p ) ) {
1873 return 0;
1874 }
1875
1876 point l;
1877 submap *const current_submap = get_submap_at( p, l );
1878
1879 const int tercost = current_submap->get_ter( l ).obj().movecost;
1880 if( tercost == 0 ) {
1881 return 0;
1882 }
1883
1884 const int furncost = current_submap->get_furn( l ).obj().movecost;
1885 if( furncost < 0 ) {
1886 return 0;
1887 }
1888
1889 const int cost = tercost + furncost;
1890 return cost > 0 ? cost : 0;
1891}

References submap::get_furn(), get_submap_at(), submap::get_ter(), inbounds(), map_data_common_t::movecost, and int_id< T >::obj().

Referenced by move_cost_ter_furn(), passable_ter_furn(), and vehicle_wheel_traction().

◆ move_cost_ter_furn() [2/2]

int map::move_cost_ter_furn ( point  p) const
inline

Definition at line 579 of file map.h.

579 {
580 return move_cost_ter_furn( tripoint( p, abs_sub.z ) );
581 }
int move_cost_ter_furn(const tripoint &p) const
Similar behavior to move_cost(), but ignores vehicles.
Definition: map.cpp:1870

References abs_sub, move_cost_ter_furn(), and tripoint::z.

◆ move_vehicle()

vehicle * map::move_vehicle ( vehicle veh,
const tripoint dp,
const tileray facing 
)

Definition at line 580 of file map.cpp.

581{
582 if( dp == tripoint_zero ) {
583 debugmsg( "Empty displacement vector" );
584 return &veh;
585 } else if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ) {
586 debugmsg( "Invalid displacement vector: %d, %d, %d", dp.x, dp.y, dp.z );
587 return &veh;
588 }
589 // Split the movement into horizontal and vertical for easier processing
590 if( dp.xy() != point_zero && dp.z != 0 ) {
591 vehicle *const new_pointer = move_vehicle( veh, tripoint( dp.xy(), 0 ), facing );
592 if( !new_pointer ) {
593 return nullptr;
594 }
595
596 vehicle *const result = move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), facing );
597 if( !result ) {
598 return nullptr;
599 }
600
601 result->is_falling = false;
602 return result;
603 }
604 const bool vertical = dp.z != 0;
605 // Ensured by the splitting above
606 assert( vertical == ( dp.xy() == point_zero ) );
607
608 const int target_z = dp.z + veh.sm_pos.z;
609 if( target_z < -OVERMAP_DEPTH || target_z > OVERMAP_HEIGHT ) {
610 return &veh;
611 }
612
613 veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point() );
614
615 // cancel out any movement of the vehicle due only to a change in pivot
616 tripoint dp1 = dp - veh.pivot_displacement();
617
618 if( !vertical ) {
619 veh.adjust_zlevel( 1, dp1 );
620 }
621
622 int impulse = 0;
623
624 std::vector<veh_collision> collisions;
625
626 // Find collisions
627 // Velocity of car before collision
628 // Split into vertical and horizontal movement
629 const int &coll_velocity = vertical ? veh.vertical_velocity : veh.velocity;
630 const int velocity_before = coll_velocity;
631 if( velocity_before == 0 && !veh.is_rotorcraft() && !veh.is_flying_in_air() ) {
632 debugmsg( "%s tried to move %s with no velocity",
633 veh.name, vertical ? "vertically" : "horizontally" );
634 return &veh;
635 }
636
637 bool veh_veh_coll_flag = false;
638 // Try to collide multiple times
639 size_t collision_attempts = 10;
640 do {
641 collisions.clear();
642 veh.collision( collisions, dp1, false );
643
644 // Vehicle collisions
645 std::map<vehicle *, std::vector<veh_collision> > veh_collisions;
646 for( auto &coll : collisions ) {
647 if( coll.type != veh_coll_veh ) {
648 continue;
649 }
650
651 veh_veh_coll_flag = true;
652 // Only collide with each vehicle once
653 veh_collisions[ static_cast<vehicle *>( coll.target ) ].push_back( coll );
654 }
655
656 for( auto &pair : veh_collisions ) {
657 impulse += vehicle_vehicle_collision( veh, *pair.first, pair.second );
658 }
659
660 // Non-vehicle collisions
661 for( const auto &coll : collisions ) {
662 if( coll.type == veh_coll_veh ) {
663 continue;
664 }
665 if( coll.part > veh.part_count() ||
666 veh.part( coll.part ).removed ) {
667 continue;
668 }
669
670 point collision_point = veh.part( coll.part ).mount;
671 const int coll_dmg = coll.imp;
672 // Shock damage, if the target part is a rotor treat as an aimed hit.
673 if( veh.part_info( coll.part ).rotor_diameter() > 0 ) {
674 veh.damage( coll.part, coll_dmg, DT_BASH, true );
675 } else {
676 impulse += coll_dmg;
677 veh.damage( coll.part, coll_dmg, DT_BASH );
678 veh.damage_all( coll_dmg / 2, coll_dmg, DT_BASH, collision_point );
679 }
680 }
681
682 // prevent vehicle bouncing after the first collision
683 if( vertical && velocity_before < 0 && coll_velocity > 0 ) {
684 veh.vertical_velocity = 0; // also affects `coll_velocity` and thus exits the loop
685 }
686
687 } while( collision_attempts-- > 0 && coll_velocity != 0 &&
688 sgn( coll_velocity ) == sgn( velocity_before ) &&
689 !collisions.empty() && !veh_veh_coll_flag );
690
691 const int velocity_after = coll_velocity;
692 bool can_move = velocity_after != 0 && sgn( velocity_after ) == sgn( velocity_before );
693 if( dp.z != 0 && veh.is_rotorcraft() ) {
694 can_move = true;
695 }
696 units::angle coll_turn = 0_degrees;
697 if( impulse > 0 ) {
698 coll_turn = shake_vehicle( veh, velocity_before, facing.dir() );
699 veh.stop_autodriving();
700 const int volume = std::min<int>( 100, std::sqrt( impulse ) );
701 // TODO: Center the sound at weighted (by impulse) average of collisions
703 false, "smash_success", "hit_vehicle" );
704 }
705
706 if( veh_veh_coll_flag ) {
707 // Break here to let the hit vehicle move away
708 return nullptr;
709 }
710
711 // If not enough wheels, mess up the ground a bit.
712 if( !vertical && !veh.valid_wheel_config() && !veh.is_in_water() && !veh.is_flying_in_air() &&
713 dp.z == 0 ) {
714 veh.velocity += veh.velocity < 0 ? 2000 : -2000;
715 for( const auto &p : veh.get_points() ) {
716 const ter_id &pter = ter( p );
717 if( pter == t_dirt || pter == t_grass ) {
718 ter_set( p, t_dirtmound );
719 }
720 }
721 }
722
723 const units::angle last_turn_dec = 1_degrees;
724 if( veh.last_turn < 0_degrees ) {
725 veh.last_turn += last_turn_dec;
726 if( veh.last_turn > -last_turn_dec ) {
727 veh.last_turn = 0_degrees;
728 }
729 } else if( veh.last_turn > 0_degrees ) {
730 veh.last_turn -= last_turn_dec;
731 if( veh.last_turn < last_turn_dec ) {
732 veh.last_turn = 0_degrees;
733 }
734 }
735
736 Character &player_character = get_player_character();
737 const bool seen = sees_veh( player_character, veh, false );
738
739 if( can_move || ( vertical && veh.is_falling ) ) {
740 // Accept new direction
741 if( veh.skidding ) {
742 veh.face.init( veh.turn_dir );
743 } else {
744 veh.face = facing;
745 }
746
747 veh.move = facing;
748 if( coll_turn != 0_degrees ) {
749 veh.skidding = true;
750 veh.turn( coll_turn );
751 }
752 veh.on_move();
753 // Actually change position
754 displace_vehicle( veh, dp1 );
755 veh.shift_zlevel();
756 } else if( !vertical ) {
757 veh.stop();
758 }
760 // If the PC is in the currently moved vehicle, adjust the
761 // view offset.
762 if( g->u.controlling_vehicle && veh_pointer_or_null( veh_at( g->u.pos() ) ) == &veh ) {
763 g->calc_driving_offset( &veh );
764 if( veh.skidding && can_move ) {
765 // TODO: Make skid recovery in air hard
767 }
768 }
769 // Now we're gonna handle traps we're standing on (if we're still moving).
770 if( !vertical && can_move ) {
771 const auto wheel_indices = veh.wheelcache; // Don't use a reference here, it causes a crash.
772
773 // Values to deal with crushing items.
774 // The math needs to be floating-point to work, so the values might as well be.
775 const float vehicle_grounded_wheel_area = static_cast<int>( vehicle_wheel_traction( veh, true ) );
776 const float weight_to_damage_factor = 0.05; // Nobody likes a magic number.
777 const float vehicle_mass_kg = to_kilogram( veh.total_mass() );
778
779 for( auto &w : wheel_indices ) {
780 const tripoint wheel_p = veh.global_part_pos3( w );
781 if( one_in( 2 ) && displace_water( wheel_p ) ) {
782 sounds::sound( wheel_p, 4, sounds::sound_t::movement, _( "splash!" ), false,
783 "environment", "splash" );
784 }
785
786 veh.handle_trap( wheel_p, w );
787 if( !has_flag( "SEALED", wheel_p ) ) {
788 const float wheel_area = veh.part( w ).wheel_area();
789
790 // Damage is calculated based on the weight of the vehicle,
791 // The area of it's wheels, and the area of the wheel running over the items.
792 // This number is multiplied by weight_to_damage_factor to get reasonable results, damage-wise.
793 const int wheel_damage = static_cast<int>( ( ( wheel_area / vehicle_grounded_wheel_area ) *
794 vehicle_mass_kg ) * weight_to_damage_factor );
795
796 //~ %1$s: vehicle name
797 smash_items( wheel_p, wheel_damage, string_format( _( "weight of %1$s" ), veh.disp_name() ),
798 false );
799 }
800 }
801 }
802 if( veh.is_towing() ) {
803 veh.do_towing_move();
804 // veh.do_towing_move() may cancel towing, so we need to recheck is_towing here
805 if( veh.is_towing() && veh.tow_data.get_towed()->tow_cable_too_far() ) {
806 add_msg( m_info, _( "A towing cable snaps off of %s." ),
807 veh.tow_data.get_towed()->disp_name() );
808 veh.tow_data.get_towed()->invalidate_towing( true );
809 }
810 }
811 // Redraw scene, but only if the player is not engaged in an activity and
812 // the vehicle was seen before or after the move.
813 if( !player_character.activity && ( seen || sees_veh( player_character, veh, true ) ) ) {
814 g->invalidate_main_ui_adaptor();
818 }
819 return &veh;
820}
player_activity activity
Definition: character.h:1578
float vehicle_wheel_traction(const vehicle &veh, bool ignore_movement_modifiers=false) const
void smash_items(const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
Tries to smash the items at the given tripoint.
Definition: map.cpp:3074
bool displace_vehicle(vehicle &veh, const tripoint &dp)
Definition: map.cpp:1184
bool displace_water(const tripoint &dp)
Definition: map.cpp:1344
units::angle shake_vehicle(vehicle &veh, int velocity_before, units::angle direction)
vehicle * move_vehicle(vehicle &veh, const tripoint &dp, const tileray &facing)
Definition: map.cpp:580
float vehicle_vehicle_collision(vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
Definition: map.cpp:822
void init(point ad)
Definition: tileray.cpp:27
vehicle * get_towed() const
Definition: vehicle.h:157
void turn(units::angle deg)
void adjust_zlevel(int idir=0, const tripoint &offset=tripoint_zero)
bool is_rotorcraft() const
is the vehicle flying? is it a rotorcraft?
Definition: vehicle.cpp:4219
std::set< tripoint > & get_points(bool force_refresh=false)
Definition: vehicle.cpp:6783
bool skidding
Definition: vehicle.h:1731
units::angle last_turn
Definition: vehicle.h:1661
bool is_towing() const
Definition: vehicle.cpp:6057
int vertical_velocity
Definition: vehicle.h:1654
int velocity
Definition: vehicle.h:1650
void damage_all(int dmg1, int dmg2, damage_type type, point impact)
Definition: vehicle.cpp:6465
bool valid_wheel_config() const
Definition: vehicle.cpp:4482
units::mass total_mass() const
Definition: vehicle.cpp:3308
std::vector< int > wheelcache
Definition: vehicle.h:1550
void check_falling_or_floating()
bool is_flying_in_air() const
Definition: vehicle.cpp:4229
towing_data tow_data
Definition: vehicle.h:1676
point pivot_point() const
Definition: vehicle.cpp:5849
int damage(int p, int dmg, damage_type type=DT_BASH, bool aimed=true)
Definition: vehicle.cpp:6386
bool is_in_water(bool deep_water=false) const
is the vehicle mostly in water or mostly on fairly dry land?
Definition: vehicle.cpp:4244
void possibly_recover_from_skid()
tileray move
Definition: vehicle.h:1682
void stop_autodriving(bool apply_brakes=true)
bool collision(std::vector< veh_collision > &colls, const tripoint &dp, bool just_detect, bool bash_floor=false)
void precalc_mounts(int idir, units::angle dir, point pivot)
Definition: vehicle.cpp:3152
bool tow_cable_too_far() const
Definition: vehicle.cpp:6186
std::string disp_name() const
void handle_trap(const tripoint &p, int part)
bool is_falling
Definition: vehicle.h:1737
void shift_zlevel()
units::angle turn_dir
Definition: vehicle.h:1659
point pivot_displacement() const
Definition: vehicle.cpp:3346
void do_towing_move()
Definition: vehicle.cpp:5958
void on_move()
Definition: vehicle.cpp:5299
int rotor_diameter() const
Definition: veh_type.cpp:910
@ m_info
Definition: enums.h:265
constexpr int sgn(const T x)
Definition: enums.h:8
static bool sees_veh(const Creature &c, vehicle &veh, bool force_recalc)
Definition: map.cpp:572
void redraw_invalidated()
Redraw all invalidated windows without invalidating the top window.
Definition: ui_manager.cpp:394
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16
constexpr value_type to_kilogram(const quantity< value_type, mass_in_milligram_tag > &v)
Definition: units_mass.h:74
void refresh_display()
Make changes made to the display visible to the user immediately.
static constexpr tripoint tripoint_zero
Definition: point.h:259
int wheel_area() const
Get wheel diameter times wheel width (inches^2) or return 0 if part is not wheel.
bool removed
true if this part is removed.
Definition: vehicle_part.h:249
point mount
mount point: x is on the forward/backward axis, y is on the left/right axis
Definition: vehicle_part.h:206
@ veh_coll_veh
Definition: vehicle.h:100

References _, Character::activity, add_msg(), vehicle::adjust_zlevel(), vehicle::check_falling_or_floating(), vehicle::collision(), sounds::combat, vehicle::damage(), vehicle::damage_all(), debugmsg, tileray::dir(), vehicle::disp_name(), displace_vehicle(), displace_water(), vehicle::do_towing_move(), DT_BASH, vehicle::face, g, get_player_character(), vehicle::get_points(), towing_data::get_towed(), vehicle::global_part_pos3(), vehicle::global_pos3(), vehicle::handle_trap(), has_flag(), tileray::init(), inp_mngr, vehicle::invalidate_towing(), vehicle::is_falling, vehicle::is_flying_in_air(), vehicle::is_in_water(), vehicle::is_rotorcraft(), vehicle::is_towing(), vehicle::last_turn, m_info, vehicle_part::mount, vehicle::move, move_vehicle(), sounds::movement, vehicle::name, vehicle::on_move(), one_in(), OVERMAP_HEIGHT, vehicle::part(), vehicle::part_count(), vehicle::part_info(), vehicle::pivot_displacement(), vehicle::pivot_point(), point_zero, vehicle::possibly_recover_from_skid(), vehicle::precalc_mounts(), input_manager::pump_events(), ui_manager::redraw_invalidated(), refresh_display(), vehicle_part::removed, vpart_info::rotor_diameter(), sees_veh(), sgn(), shake_vehicle(), vehicle::shift_zlevel(), vehicle::skidding, vehicle::sm_pos, smash_items(), sounds::sound(), vehicle::stop(), vehicle::stop_autodriving(), string_format(), t_dirt, t_dirtmound, t_grass, ter(), ter_set(), units::to_kilogram(), vehicle::total_mass(), vehicle::tow_cable_too_far(), vehicle::tow_data, tripoint_zero, vehicle::turn(), vehicle::turn_dir, vehicle::valid_wheel_config(), veh_at(), veh_coll_veh, veh_pointer_or_null(), vehicle_vehicle_collision(), vehicle_wheel_traction(), vehicle::velocity, vehicle::vertical_velocity, vehicle_part::wheel_area(), vehicle::wheelcache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by move_vehicle().

◆ name() [1/2]

◆ name() [2/2]

std::string map::name ( point  p)
inline

Definition at line 779 of file map.h.

779 {
780 return name( tripoint( p, abs_sub.z ) );
781 }

References abs_sub, name(), and tripoint::z.

◆ obscured_by_vehicle_rotation()

bool map::obscured_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.

Definition at line 6660 of file map.cpp.

6661{
6662 if( !inbounds( from ) || !inbounds( to ) ) {
6663 return false;
6664 }
6665
6666 if( from.z != to.z ) {
6667 //Split it into two checks, one for each z level
6668 tripoint flattened = {from.xy(), to.z};
6669 if( obscured_by_vehicle_rotation( flattened, to ) ) {
6670 return true;
6671 }
6672 }
6673
6674 point delta = to.xy() - from.xy();
6675
6676 auto cache = get_cache( from.z ).vehicle_obscured_cache;
6677
6678 if( delta == point_north_west ) {
6679 return cache[from.x][from.y].nw;
6680 }
6681
6682 if( delta == point_north_east ) {
6683 return cache[from.x][from.y].ne;
6684 }
6685
6686 if( delta == point_south_west ) {
6687 return cache[to.x][to.y].ne;
6688 }
6689 if( delta == point_south_east ) {
6690 return cache[to.x][to.y].nw;
6691 }
6692
6693 return false;
6694}
bool obscured_by_vehicle_rotation(const tripoint &from, const tripoint &to) const
Checks if a rotated vehicle is blocking diagonal vision, tripoints must be adjacent.
Definition: map.cpp:6660
bool nw
Definition: map.h:297

References get_cache(), inbounds(), diagonal_blocks::nw, obscured_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obscured_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by obscured_by_vehicle_rotation(), and sees().

◆ obstacle_coverage()

int map::obstacle_coverage ( const tripoint loc1,
const tripoint loc2 
) const

Returns coverage of target in relation to the observer.

Target is loc2, observer is loc1. First tile from the target is an obstacle, which has the coverage value. If there's no obstacle adjacent to the target - no coverage.

Definition at line 6357 of file map.cpp.

6358{
6359 // Can't hide if you are standing on furniture, or non-flat slowing-down terrain tile.
6360 if( furn( loc2 ).obj().id || ( move_cost( loc2 ) > 2 && !has_flag_ter( TFLAG_FLAT, loc2 ) ) ) {
6361 return 0;
6362 }
6363 const point a( std::abs( loc1.x - loc2.x ) * 2, std::abs( loc1.y - loc2.y ) * 2 );
6364 int offset = std::min( a.x, a.y ) - ( std::max( a.x, a.y ) / 2 );
6365 tripoint obstaclepos;
6366 bresenham( loc2, loc1, offset, 0, [&obstaclepos]( const tripoint & new_point ) {
6367 // Only adjacent tile between you and enemy is checked for cover.
6368 obstaclepos = new_point;
6369 return false;
6370 } );
6371 if( const auto obstacle_f = furn( obstaclepos ) ) {
6372 return obstacle_f->coverage;
6373 }
6374 if( const auto vp = veh_at( obstaclepos ) ) {
6375 if( vp->obstacle_at_part() ) {
6376 return 60;
6377 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) ) {
6378 return 45;
6379 }
6380 }
6381 return ter( obstaclepos )->coverage;
6382}
@ TFLAG_FLAT
Definition: mapdata.h:318

References a, bresenham(), map_data_common_t::coverage, furn(), has_flag_ter(), move_cost(), ter(), TFLAG_FLAT, veh_at(), VPFLAG_AISLE, tripoint::x, and tripoint::y.

◆ obstacle_name()

std::string map::obstacle_name ( const tripoint p)

Returns the name of the obstacle at p that might be blocking movement/projectiles/etc.

Note that this only accounts for vehicles, terrain, and furniture.

Definition at line 1400 of file map.cpp.

1401{
1402 if( const std::optional<vpart_reference> vp = veh_at( p ).obstacle_at_part() ) {
1403 return vp->info().name();
1404 }
1405 return name( p );
1406}

References name(), and veh_at().

Referenced by avatar_action::move().

◆ obstructed_by_vehicle_rotation()

bool map::obstructed_by_vehicle_rotation ( const tripoint from,
const tripoint to 
) const

Checks if a rotated vehicle is blocking diagonal movement, tripoints must be adjacent.

Definition at line 6623 of file map.cpp.

6624{
6625 if( !inbounds( from ) || !inbounds( to ) ) {
6626 return false;
6627 }
6628
6629 if( from.z != to.z ) {
6630 //Split it into two checks, one for each z level
6631 tripoint flattened = {from.xy(), to.z};
6632 if( obstructed_by_vehicle_rotation( flattened, to ) ) {
6633 return true;
6634 }
6635 }
6636
6637 point delta = to.xy() - from.xy();
6638
6639 auto cache = get_cache( from.z ).vehicle_obstructed_cache;
6640
6641 if( delta == point_north_west ) {
6642 return cache[from.x][from.y].nw;
6643 }
6644
6645 if( delta == point_north_east ) {
6646 return cache[from.x][from.y].ne;
6647 }
6648
6649 if( delta == point_south_west ) {
6650 return cache[to.x][to.y].ne;
6651 }
6652 if( delta == point_south_east ) {
6653 return cache[to.x][to.y].nw;
6654 }
6655
6656 return false;
6657}
diagonal_blocks vehicle_obstructed_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:339

References get_cache(), inbounds(), diagonal_blocks::nw, obstructed_by_vehicle_rotation(), point_north_east, point_north_west, point_south_east, point_south_west, level_cache::vehicle_obstructed_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by add_splatter_trail(), monster::can_squeeze_to(), clear_path(), clear_shot_reach(), game::fling_creature(), gas_can_spread_to(), game::knockback(), avatar_action::move(), obstructed_by_vehicle_rotation(), game::peek(), npc::pick_up_item(), process_fields_in_submap(), and propagate_field().

◆ on_vehicle_moved()

void map::on_vehicle_moved ( int  smz)

Callback invoked when a vehicle has moved.

Definition at line 465 of file map.cpp.

466{
470 set_floor_cache_dirty( smz + 1 );
472}

References set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), and set_transparency_cache_dirty().

Referenced by displace_vehicle().

◆ open_door()

bool map::open_door ( const tripoint p,
bool  inside,
bool  check_only = false 
)

Definition at line 3978 of file map.cpp.

3979{
3980 avatar &you = get_avatar();
3981 const auto &ter = this->ter( p ).obj();
3982 const auto &furn = this->furn( p ).obj();
3983
3984 if( ter.open ) {
3985 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3986 return false;
3987 }
3988 if( you.is_mounted() ) {
3989 auto mon = you.mounted_creature.get();
3990 if( !mon->has_flag( MF_RIDEABLE_MECH ) ) {
3991 add_msg( m_info, _( "You can't open things while you're riding." ) );
3992 return false;
3993 }
3994 }
3995 if( !check_only ) {
3996 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3997 "open_door", ter.id.str() );
3998 ter_set( p, ter.open );
3999
4000 if( ( you.has_trait( trait_id( "SCHIZOPHRENIC" ) ) || you.has_artifact_with( AEP_SCHIZO ) )
4001 && one_in( 50 ) && !ter.has_flag( "TRANSPARENT" ) ) {
4002 tripoint mp = p + -2 * you.pos().xy() + tripoint( 2 * p.x, 2 * p.y, p.z );
4003 g->spawn_hallucination( mp );
4004 }
4005 }
4006
4007 return true;
4008 } else if( furn.open ) {
4009 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
4010 return false;
4011 }
4012 if( you.is_mounted() ) {
4013 auto mon = you.mounted_creature.get();
4014 if( !mon->has_flag( MF_RIDEABLE_MECH ) ) {
4015 add_msg( m_info, _( "You can't open things while you're riding." ) );
4016 return false;
4017 }
4018 }
4019
4020 if( !check_only ) {
4021 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
4022 "open_door", furn.id.str() );
4023 furn_set( p, furn.open );
4024 }
4025
4026 return true;
4027 } else if( const optional_vpart_position vp = veh_at( p ) ) {
4028 int openable = vp->vehicle().next_part_to_open( vp->part_index(), true );
4029 if( openable >= 0 ) {
4030 if( you.is_mounted() ) {
4031 auto mon = you.mounted_creature.get();
4032 if( !mon->has_flag( MF_RIDEABLE_MECH ) ) {
4033 add_msg( m_info, _( "You can't open things while you're riding." ) );
4034 return false;
4035 }
4036 }
4037 if( !check_only ) {
4038 if( !vp->vehicle().handle_potential_theft( you ) ) {
4039 return false;
4040 }
4041 vp->vehicle().open_all_at( openable );
4042 }
4043
4044 return true;
4045 }
4046
4047 return false;
4048 }
4049
4050 return false;
4051}
avatar & get_avatar()
Definition: avatar.cpp:105
virtual bool has_artifact_with(art_effect_passive effect) const
Definition: character.cpp:3213
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:101
Definition: avatar.h:55
@ AEP_SCHIZO
Definition: enums.h:128

References _, add_msg(), AEP_SCHIZO, furn(), furn_set(), g, get_avatar(), Character::has_artifact_with(), has_flag(), Character::has_trait(), int_id< T >::id(), Character::is_mounted(), m_info, MF_RIDEABLE_MECH, Character::mounted_creature, sounds::movement, int_id< T >::obj(), one_in(), Character::pos(), sounds::sound(), string_id< T >::str(), ter(), ter_set(), veh_at(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by npc::can_open_door(), avatar_action::move(), and rate_location().

◆ operator=() [1/2]

map & map::operator= ( const map )
delete

◆ operator=() [2/2]

map & map::operator= ( map &&  )
default

◆ partial_con_at()

partial_con * map::partial_con_at ( const tripoint p)

Definition at line 5274 of file map.cpp.

5275{
5276 if( !inbounds( p ) ) {
5277 return nullptr;
5278 }
5279 point l;
5280 submap *const current_submap = get_submap_at( p, l );
5281 auto it = current_submap->partial_constructions.find( tripoint( l, p.z ) );
5282 if( it != current_submap->partial_constructions.end() ) {
5283 return &it->second;
5284 }
5285 return nullptr;
5286}
std::map< tripoint, partial_con > partial_constructions
Definition: submap.h:219

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by player_activity::get_progress_message(), and game::print_trap_info().

◆ partial_con_remove()

void map::partial_con_remove ( const tripoint p)

Definition at line 5288 of file map.cpp.

5289{
5290 if( !inbounds( p ) ) {
5291 return;
5292 }
5293 point l;
5294 submap *const current_submap = get_submap_at( p, l );
5295 current_submap->partial_constructions.erase( tripoint( l, p.z ) );
5296}

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

◆ partial_con_set()

void map::partial_con_set ( const tripoint p,
const partial_con con 
)

Definition at line 5298 of file map.cpp.

5299{
5300 if( !inbounds( p ) ) {
5301 return;
5302 }
5303 point l;
5304 submap *const current_submap = get_submap_at( p, l );
5305 if( !current_submap->partial_constructions.emplace( tripoint( l, p.z ), con ).second ) {
5306 debugmsg( "set partial con on top of terrain which already has a partial con" );
5307 }
5308}

References debugmsg, get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

◆ passable() [1/2]

◆ passable() [2/2]

bool map::passable ( point  p) const
inline

Definition at line 570 of file map.h.

570 {
571 return passable( tripoint( p, abs_sub.z ) );
572 }

References abs_sub, passable(), and tripoint::z.

◆ passable_ter_furn()

bool map::passable_ter_furn ( const tripoint p) const

Definition at line 1898 of file map.cpp.

1899{
1900 return move_cost_ter_furn( p ) != 0;
1901}

References move_cost_ter_furn().

Referenced by impassable_ter_furn(), and avatar_action::move().

◆ pl_line_of_sight()

bool map::pl_line_of_sight ( const tripoint t,
int  max_range 
) const

Uses the map cache to tell if the player could see the given square.

pl_sees implies pl_line_of_sight Used for infrared.

Definition at line 831 of file lightmap.cpp.

832{
833 if( !inbounds( t ) ) {
834 return false;
835 }
836
837 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
838 // Out of range!
839 return false;
840 }
841
842 const auto &map_cache = get_cache_ref( t.z );
843 // Any epsilon > 0 is fine - it means lightmap processing visited the point
844 return map_cache.seen_cache[t.x][t.y] > 0.0f ||
845 map_cache.camera_cache[t.x][t.y] > 0.0f;
846}

References g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

◆ pl_sees()

bool map::pl_sees ( const tripoint t,
int  max_range 
) const

Whether the player character (g->u) can see the given square (local map coordinates).

This only checks the transparency of the path to the target, the light level is not checked.

Parameters
tTarget point to look at
max_rangeAll squares that are further away than this are invisible. Ignored if smaller than 0.

Definition at line 813 of file lightmap.cpp.

814{
815 if( !inbounds( t ) ) {
816 return false;
817 }
818
819 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
820 return false; // Out of range!
821 }
822
823 const auto &map_cache = get_cache_ref( t.z );
824 const apparent_light_info a = apparent_light_helper( map_cache, t );
825 const float light_at_player = map_cache.lm[g->u.posx()][g->u.posy()].max();
826 return !a.obstructed &&
827 ( a.apparent_light >= g->u.get_vision_threshold( light_at_player ) ||
828 map_cache.sm[t.x][t.y] > 0.0 );
829}

References a, apparent_light_helper(), g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by sounds::process_sound_markers(), and Character::sees().

◆ place_gas_pump() [1/2]

void map::place_gas_pump ( point  p,
int  charges 
)

Definition at line 5286 of file mapgen.cpp.

5287{
5288 place_gas_pump( p, charges, one_in( 4 ) ? "diesel" : "gasoline" );
5289}
void place_gas_pump(point p, int charges, const std::string &fuel_type)
Definition: mapgen.cpp:5278

References one_in(), and place_gas_pump().

◆ place_gas_pump() [2/2]

void map::place_gas_pump ( point  p,
int  charges,
const std::string &  fuel_type 
)

Definition at line 5278 of file mapgen.cpp.

5279{
5280 item fuel( fuel_type, calendar::start_of_cataclysm );
5281 fuel.charges = charges;
5282 add_item( p, fuel );
5283 ter_set( p, ter_id( fuel.fuel_pump_terrain() ) );
5284}

References add_item(), item::charges, item::fuel_pump_terrain(), calendar::start_of_cataclysm, ter_id, and ter_set().

Referenced by jmapgen_gaspump::apply(), mapgen_tutorial(), and place_gas_pump().

◆ place_items() [1/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const tripoint p1,
const tripoint p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)

Place items from item group in the rectangle f - t.

Several items may be spawned on different places. Several items may spawn at once (at one place) when the item group says so (uses item_group::items_from which may return several items at once).

Parameters
locCurrent location of items to be placed
chanceChance for more items. A chance of 100 creates 1 item all the time, otherwise it's the chance that more items will be created (place items until the random roll with that chance fails). The chance is used for the first item as well, so it may not spawn an item at all. Values <= 0 or > 100 are invalid.
p1One corner of rectangle in which to spawn items
p2Second corner of rectangle in which to spawn items
ongrassIf false the items won't spawn on flat terrain (grass, floor, ...).
turnThe birthday that the created items shall have.
magazinepercentage chance item will contain the default magazine
ammopercentage chance item will be filled with default ammo
Returns
vector containing all placed items

Definition at line 5351 of file mapgen.cpp.

5355{
5356 // TODO: implement for 3D
5357 std::vector<item *> res;
5358
5359 if( chance > 100 || chance <= 0 ) {
5360 debugmsg( "map::place_items() called with an invalid chance (%d)", chance );
5361 return res;
5362 }
5363 if( !item_group::group_is_defined( loc ) ) {
5364 // TODO: fix point types
5366 const oter_id &oid = overmap_buffer.ter( omt );
5367 debugmsg( "place_items: invalid item group '%s', om_terrain = '%s' (%s)",
5368 loc.c_str(), oid.id().c_str(), oid->get_mapgen_id().c_str() );
5369 return res;
5370 }
5371
5372 const float spawn_rate = get_option<float>( "ITEM_SPAWNRATE" );
5373 int spawn_count = roll_remainder( chance * spawn_rate / 100.0f );
5374 for( int i = 0; i < spawn_count; i++ ) {
5375 // Might contain one item or several that belong together like guns & their ammo
5376 int tries = 0;
5377 auto is_valid_terrain = [this, ongrass]( point p ) {
5378 auto &terrain = ter( p ).obj();
5379 return terrain.movecost == 0 &&
5380 !terrain.has_flag( "PLACE_ITEM" ) &&
5381 !ongrass &&
5382 !terrain.has_flag( "FLAT" );
5383 };
5384
5385 point p;
5386 do {
5387 p.x = rng( p1.x, p2.x );
5388 p.y = rng( p1.y, p2.y );
5389 tries++;
5390 } while( is_valid_terrain( p ) && tries < 20 );
5391 if( tries < 20 ) {
5392 auto put = put_items_from_loc( loc, tripoint( p, abs_sub.z ), turn );
5393 res.insert( res.end(), put.begin(), put.end() );
5394 }
5395 }
5396 for( auto e : res ) {
5397 if( e->is_tool() || e->is_gun() || e->is_magazine() ) {
5398 if( rng( 0, 99 ) < magazine && !e->magazine_integral() && !e->magazine_current() ) {
5399 e->put_in( item( e->magazine_default(), e->birthday() ) );
5400 }
5401 if( rng( 0, 99 ) < ammo && e->ammo_remaining() == 0 ) {
5402 e->ammo_set( e->ammo_default(), e->ammo_capacity() );
5403 }
5404 }
5405 }
5406 return res;
5407}
constexpr scale omt
Definition: coordinates.h:32
bool group_is_defined(const item_group_id &group_id)
Check whether an item group of the given id exists.
Definition: item_group.cpp:603

References abs_sub, string_id< T >::c_str(), debugmsg, get_abs_sub(), oter_t::get_mapgen_id(), item_group::group_is_defined(), int_id< T >::id(), int_id< T >::obj(), coords::omt, overmap_buffer, put_items_from_loc(), rng(), roll_remainder(), sm_to_omt_copy(), ter(), overmapbuffer::ter(), terrain, calendar::turn, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by jmapgen_item_group::apply(), draw_mine(), draw_office_tower(), draw_slimepit(), mapgen_ants_food(), mapgen_ants_larvae(), mapgen_ants_larvae_acid(), mapgen_ants_queen(), mapgen_ants_queen_acid(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_hive(), mapgen_parking_lot(), mapgen_road(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_military(), MapExtras::mx_minefield(), MapExtras::mx_roadblock(), MapExtras::mx_roadworks(), MapExtras::mx_science(), MapExtras::mx_supplydrop(), place_items(), place_vending(), mission_start::ranch_nurse_8(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), and science_room().

◆ place_items() [2/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
point  p1,
point  p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)
inline

Definition at line 1309 of file map.h.

1311 {
1312 return place_items( loc, chance, tripoint( p1, abs_sub.z ), tripoint( p2, abs_sub.z ), ongrass,
1313 turn, magazine, ammo );
1314 }

References abs_sub, place_items(), calendar::turn, and tripoint::z.

◆ place_npc()

character_id map::place_npc ( point  p,
const string_id< npc_template > &  type,
bool  force = false 
)

Definition at line 5319 of file mapgen.cpp.

5320{
5321 if( !force && !get_option<bool>( "STATIC_NPC" ) ) {
5322 return character_id(); //Do not generate an npc.
5323 }
5324 shared_ptr_fast<npc> temp = make_shared_fast<npc>();
5325 temp->load_npc_template( type );
5326 temp->spawn_at_precise( { abs_sub.xy() }, { p, abs_sub.z } );
5327 temp->toggle_trait( trait_NPC_STATIC_NPC );
5328 overmap_buffer.insert_npc( temp );
5329 return temp->getID();
5330}
void insert_npc(const shared_ptr_fast< npc > &who)
Adds the npc to an overmap ( based on the npcs current location ) and stores it there.
static const trait_id trait_NPC_STATIC_NPC("NPC_STATIC_NPC")
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References abs_sub, character_id, overmapbuffer::insert_npc(), overmap_buffer, trait_NPC_STATIC_NPC, type, tripoint::xy(), and tripoint::z.

Referenced by jmapgen_npc::apply(), mapgen_hive(), MapExtras::mx_bandits_block(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), and mission_start::ranch_nurse_9().

◆ place_spawns()

void map::place_spawns ( const mongroup_id group,
int  chance,
point  p1,
point  p2,
float  density,
bool  individual = false,
bool  friendly = false,
const std::string &  name = "NONE",
int  mission_id = -1 
)

Definition at line 5228 of file mapgen.cpp.

5231{
5232 if( !group.is_valid() ) {
5233 // TODO: fix point types
5235 const oter_id &oid = overmap_buffer.ter( omt );
5236 debugmsg( "place_spawns: invalid mongroup '%s', om_terrain = '%s' (%s)", group.c_str(),
5237 oid.id().c_str(), oid->get_mapgen_id().c_str() );
5238 return;
5239 }
5240
5241 // Set chance to be 1 or less to guarantee spawn, else set higher than 1
5242 if( !one_in( chance ) ) {
5243 return;
5244 }
5245
5246 float spawn_density = 1.0f;
5248 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
5249 } else {
5250 spawn_density = get_option< float >( "SPAWN_DENSITY" );
5251 }
5252
5253 float multiplier = density * spawn_density;
5254 // Only spawn 1 creature if individual flag set, else scale by density
5255 float thenum = individual ? 1 : ( multiplier * rng_float( 10.0f, 50.0f ) );
5256 int num = roll_remainder( thenum );
5257
5258 // GetResultFromGroup decrements num
5259 while( num > 0 ) {
5260 int tries = 10;
5261 point p;
5262
5263 // Pick a spot for the spawn
5264 do {
5265 p.x = rng( p1.x, p2.x );
5266 p.y = rng( p1.y, p2.y );
5267 tries--;
5268 } while( impassable( p ) && tries > 0 );
5269
5270 // Pick a monster type
5272
5273 add_spawn( spawn_details.name, spawn_details.pack_size, { p, abs_sub.z },
5274 friendly, -1, mission_id, name );
5275 }
5276}
group
Definition: sounds.h:125

References add_spawn(), string_id< T >::c_str(), debugmsg, friendly, get_abs_sub(), oter_t::get_mapgen_id(), MonsterGroupManager::GetResultFromGroup(), int_id< T >::id(), impassable(), MonsterGroupManager::is_animal(), name(), MonsterGroupResult::name, num, coords::omt, one_in(), overmap_buffer, MonsterGroupResult::pack_size, rng(), rng_float(), roll_remainder(), sm_to_omt_copy(), overmapbuffer::ter(), point::x, and point::y.

Referenced by add_monsters(), jmapgen_monster_group::apply(), create_anomaly(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_military(), MapExtras::mx_pond(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), MapExtras::mx_science(), and science_room().

◆ place_toilet()

void map::place_toilet ( point  p,
int  charges = 6 * 4 
)

Definition at line 5291 of file mapgen.cpp.

5292{
5293 item water( "water", calendar::start_of_cataclysm );
5294 water.charges = charges;
5295 add_item( p, water );
5296 furn_set( p, f_toilet );
5297}

References add_item(), item::charges, f_toilet, furn_set(), and calendar::start_of_cataclysm.

Referenced by jmapgen_toilet::apply(), and mapf::formatted_set_simple().

◆ place_vending()

void map::place_vending ( point  p,
const item_group_id type,
bool  reinforced = false 
)

Definition at line 5299 of file mapgen.cpp.

5300{
5301 if( reinforced ) {
5303 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5304 } else {
5305 if( one_in( 2 ) ) {
5306 furn_set( p, f_vending_o );
5307 for( const auto &loc : points_in_radius( { p, abs_sub.z }, 1 ) ) {
5308 if( one_in( 4 ) ) {
5309 spawn_item( loc, "glass_shard", rng( 1, 2 ) );
5310 }
5311 }
5312 } else {
5313 furn_set( p, f_vending_c );
5314 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5315 }
5316 }
5317}
furn_id f_vending_o
Definition: mapdata.cpp:1112
furn_id f_vending_reinforced
Definition: mapdata.cpp:1135
furn_id f_vending_c
Definition: mapdata.cpp:1112

References abs_sub, f_vending_c, f_vending_o, f_vending_reinforced, furn_set(), one_in(), place_items(), points_in_radius(), rng(), spawn_item(), calendar::start_of_cataclysm, type, and tripoint::z.

Referenced by jmapgen_vending_machine::apply().

◆ player_in_field()

void map::player_in_field ( player u)
protected

Definition at line 1224 of file map_field.cpp.

1225{
1226 // A copy of the current field for reference. Do not add fields to it, use map::add_field
1227 field &curfield = get_field( u.pos() );
1228 // Are we inside?
1229 bool inside = false;
1230 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1231 // and what part of the vehicle we need to deal with.
1232 if( u.in_vehicle ) {
1233 if( const optional_vpart_position vp = veh_at( u.pos() ) ) {
1234 inside = vp->is_inside();
1235 }
1236 }
1237
1238 // Iterate through all field effects on this tile.
1239 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1240 // later by the field processing, which will also adjust field_count accordingly.
1241 for( auto &field_list_it : curfield ) {
1242 field_entry &cur = field_list_it.second;
1243 if( !cur.is_field_alive() ) {
1244 continue;
1245 }
1246
1247 // Do things based on what field effect we are currently in.
1248 const field_type_id ft = cur.get_field_type();
1249 if( ft == fd_web ) {
1250 // If we are in a web, can't walk in webs or are in a vehicle, get webbed maybe.
1251 // Moving through multiple webs stacks the effect.
1252 if( !u.has_trait( trait_WEB_WALKER ) && !u.in_vehicle ) {
1253 // Between 5 and 15 minus your current web level.
1254 u.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1255 // It is spent.
1256 cur.set_field_intensity( 0 );
1257 continue;
1258 // If you are in a vehicle destroy the web.
1259 // It should of been destroyed when you ran over it anyway.
1260 } else if( u.in_vehicle ) {
1261 cur.set_field_intensity( 0 );
1262 continue;
1263 }
1264 }
1265 if( ft == fd_acid ) {
1266 // Assume vehicles block acid damage entirely,
1267 // you're certainly not standing in it.
1268 if( !u.in_vehicle && !u.has_trait( trait_ACIDPROOF ) ) {
1269 int total_damage = 0;
1270 total_damage += burn_body_part( u, cur, bp_foot_l, 2 );
1271 total_damage += burn_body_part( u, cur, bp_foot_r, 2 );
1272 const bool on_ground = u.is_on_ground();
1273 if( on_ground ) {
1274 // Apply the effect to the remaining body parts
1275 total_damage += burn_body_part( u, cur, bp_leg_l, 2 );
1276 total_damage += burn_body_part( u, cur, bp_leg_r, 2 );
1277 total_damage += burn_body_part( u, cur, bp_hand_l, 2 );
1278 total_damage += burn_body_part( u, cur, bp_hand_r, 2 );
1279 total_damage += burn_body_part( u, cur, bp_torso, 2 );
1280 // Less arms = less ability to keep upright
1281 if( ( !u.has_two_arms() && one_in( 4 ) ) || one_in( 2 ) ) {
1282 total_damage += burn_body_part( u, cur, bp_arm_l, 1 );
1283 total_damage += burn_body_part( u, cur, bp_arm_r, 1 );
1284 total_damage += burn_body_part( u, cur, bp_head, 1 );
1285 }
1286 }
1287
1288 if( on_ground && total_damage > 0 ) {
1289 u.add_msg_player_or_npc( m_bad, _( "The acid burns your body!" ),
1290 _( "The acid burns <npcname>s body!" ) );
1291 } else if( total_damage > 0 ) {
1292 u.add_msg_player_or_npc( m_bad, _( "The acid burns your legs and feet!" ),
1293 _( "The acid burns <npcname>s legs and feet!" ) );
1294 } else if( on_ground ) {
1295 u.add_msg_if_player( m_warning, _( "You're lying in a pool of acid" ) );
1296 } else {
1297 u.add_msg_if_player( m_warning, _( "You're standing in a pool of acid" ) );
1298 }
1299
1300 u.check_dead_state();
1301 }
1302 }
1303 if( ft == fd_sap ) {
1304 // Sap does nothing to cars.
1305 if( !u.in_vehicle ) {
1306 // Use up sap.
1308 }
1309 }
1310 if( ft == fd_sludge ) {
1311 // Sludge is on the ground, but you are above the ground when boarded on a vehicle
1312 if( !u.in_vehicle ) {
1313 u.add_msg_if_player( m_bad, _( "The sludge is thick and sticky. You struggle to pull free." ) );
1314 u.moves -= cur.get_field_intensity() * 300;
1315 cur.set_field_intensity( 0 );
1316 }
1317 }
1318 if( ft == fd_fire ) {
1319 // Heatsink or suit prevents ALL fire damage.
1321
1322 // To modify power of a field based on... whatever is relevant for the effect.
1323 int adjusted_intensity = cur.get_field_intensity();
1324 // Burn the player. Less so if you are in a car or ON a car.
1325 if( u.in_vehicle ) {
1326 if( inside ) {
1327 adjusted_intensity -= 2;
1328 } else {
1329 adjusted_intensity -= 1;
1330 }
1331 }
1332
1333 if( adjusted_intensity >= 1 ) {
1334 // Burn message by intensity
1335 static const std::array<std::string, 4> player_burn_msg = { {
1336 translate_marker( "You burn your legs and feet!" ),
1337 translate_marker( "You're burning up!" ),
1338 translate_marker( "You're set ablaze!" ),
1339 translate_marker( "Your whole body is burning!" )
1340 }
1341 };
1342 static const std::array<std::string, 4> npc_burn_msg = { {
1343 translate_marker( "<npcname> burns their legs and feet!" ),
1344 translate_marker( "<npcname> is burning up!" ),
1345 translate_marker( "<npcname> is set ablaze!" ),
1346 translate_marker( "<npcname>s whole body is burning!" )
1347 }
1348 };
1349 static const std::array<std::string, 4> player_warn_msg = { {
1350 translate_marker( "You're standing in a fire!" ),
1351 translate_marker( "You're waist-deep in a fire!" ),
1352 translate_marker( "You're surrounded by raging fire!" ),
1353 translate_marker( "You're lying in fire!" )
1354 }
1355 };
1356
1357 const int burn_min = adjusted_intensity;
1358 const int burn_max = 3 * adjusted_intensity + 3;
1359 std::list<bodypart_id> parts_burned;
1360 int msg_num = adjusted_intensity - 1;
1361 if( !u.is_on_ground() ) {
1362 switch( adjusted_intensity ) {
1363 case 3:
1364 parts_burned.push_back( bodypart_id( "hand_l" ) );
1365 parts_burned.push_back( bodypart_id( "hand_r" ) );
1366 parts_burned.push_back( bodypart_id( "arm_l" ) );
1367 parts_burned.push_back( bodypart_id( "arm_r" ) );
1368 /* fallthrough */
1369 case 2:
1370 parts_burned.push_back( bodypart_id( "torso" ) );
1371 /* fallthrough */
1372 case 1:
1373 parts_burned.push_back( bodypart_id( "foot_l" ) );
1374 parts_burned.push_back( bodypart_id( "foot_r" ) );
1375 parts_burned.push_back( bodypart_id( "leg_l" ) );
1376 parts_burned.push_back( bodypart_id( "leg_r" ) );
1377 }
1378 } else {
1379 // Lying in the fire is BAAAD news, hits every body part.
1380 msg_num = 3;
1381 const std::vector<bodypart_id> &all_parts = u.get_all_body_parts();
1382 // HACK: Skip num_bp part
1383 for( auto bp : all_parts ) {
1384 if( bp->token != num_bp ) {
1385 parts_burned.push_back( bp );
1386 }
1387 }
1388 }
1389
1390 int total_damage = 0;
1391 for( const bodypart_id part_burned : parts_burned ) {
1392 const dealt_damage_instance dealt = u.deal_damage( nullptr, part_burned,
1393 damage_instance( DT_HEAT, rng( burn_min, burn_max ) ) );
1394 total_damage += dealt.type_damage( DT_HEAT );
1395 }
1396 if( total_damage > 0 ) {
1397 u.add_msg_player_or_npc( m_bad, _( player_burn_msg[msg_num] ), _( npc_burn_msg[msg_num] ) );
1398 } else {
1399 u.add_msg_if_player( m_warning, _( player_warn_msg[msg_num] ) );
1400 }
1401 u.check_dead_state();
1402 }
1403 }
1404
1405 }
1406 if( ft == fd_tear_gas ) {
1407 // Tear gas will both give you teargas disease and/or blind you.
1408 if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) {
1409 u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds );
1410 }
1411 if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) {
1412 u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds );
1413 }
1414 }
1415 if( ft == fd_fungal_haze ) {
1416 if( !u.has_trait( trait_M_IMMUNE ) && ( !inside || one_in( 4 ) ) ) {
1417 u.add_env_effect( effect_fungus, bp_mouth, 4, 10_minutes, num_bp );
1418 u.add_env_effect( effect_fungus, bp_eyes, 4, 10_minutes, num_bp );
1419 }
1420 }
1421 if( ft == fd_dazzling ) {
1422 if( cur.get_field_intensity() > 1 || one_in( 5 ) ) {
1423 u.add_env_effect( effect_blind, bp_eyes, 10, 10_turns );
1424 } else {
1425 u.add_env_effect( effect_blind, bp_eyes, 2, 2_turns );
1426 }
1427 }
1428
1429 if( cur.extra_radiation_min() > 0 ) {
1430 // Get irradiated by the nuclear fallout.
1431 const float rads = rng( cur.extra_radiation_min() + 1,
1432 cur.extra_radiation_max() * ( cur.extra_radiation_max() + 1 ) );
1433 const bool rad_proof = !u.irradiate( rads );
1434 // TODO: Reduce damage for rad resistant?
1435 if( cur.radiation_hurt_damage_min() > 0 && !rad_proof ) {
1437 u.hurtall( rng( cur.radiation_hurt_damage_min(), cur.radiation_hurt_damage_max() ), nullptr );
1438 }
1439 }
1440 if( ft == fd_flame_burst ) {
1441 // A burst of flame? Only hits the legs and torso.
1442 if( !inside ) {
1443 // Fireballs can't touch you inside a car.
1444 // Heatsink or suit stops fire.
1445 if( !u.has_active_bionic( bio_heatsink ) &&
1447 u.add_msg_player_or_npc( m_bad, _( "You're torched by flames!" ),
1448 _( "<npcname> is torched by flames!" ) );
1449 u.deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1450 u.deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1451 u.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_HEAT, rng( 4, 9 ) ) );
1452 u.check_dead_state();
1453 } else {
1454 u.add_msg_player_or_npc( _( "These flames do not burn you." ),
1455 _( "Those flames do not burn <npcname>." ) );
1456 }
1457 }
1458 }
1459 if( ft == fd_electricity ) {
1460 // Small universal damage based on intensity, only if not electroproofed.
1461 if( !u.is_elec_immune() ) {
1462 int total_damage = 0;
1463 for( size_t i = 0; i < num_hp_parts; i++ ) {
1464 const bodypart_id bp = convert_bp( player::hp_to_bp( static_cast<hp_part>( i ) ) ).id();
1465 const int dmg = rng( 1, cur.get_field_intensity() );
1466 total_damage += u.deal_damage( nullptr, bp, damage_instance( DT_ELECTRIC, dmg ) ).total_damage();
1467 }
1468
1469 if( total_damage > 0 ) {
1471 u.add_msg_player_or_npc( m_bad, _( "You're painfully electrocuted!" ),
1472 _( "<npcname> is shocked!" ) );
1473 u.mod_pain( total_damage / 2 );
1474 } else {
1475 u.add_msg_player_or_npc( m_bad, _( "You're shocked!" ), _( "<npcname> is shocked!" ) );
1476 }
1477 } else {
1478 u.add_msg_player_or_npc( _( "The electric cloud doesn't affect you." ),
1479 _( "The electric cloud doesn't seem to affect <npcname>." ) );
1480 }
1481 }
1482 }
1483 if( ft == fd_fatigue ) {
1484 // Assume the rift is on the ground for now to prevent issues with the player being unable access vehicle controls on the same tile due to teleportation.
1485 if( !u.in_vehicle ) {
1486 // Teleports you... somewhere.
1487 if( rng( 0, 2 ) < cur.get_field_intensity() && u.is_player() ) {
1488 add_msg( m_bad, _( "You're violently teleported!" ) );
1489 u.hurtall( cur.get_field_intensity(), nullptr );
1490 teleport::teleport( u );
1491 }
1492 }
1493 }
1494 // Why do these get removed???
1495 // Stepping on a shock vent shuts it down.
1496 if( ft == fd_shock_vent || ft == fd_acid_vent ) {
1497 cur.set_field_intensity( 0 );
1498 }
1499 if( ft == fd_bees ) {
1500 // Player is immune to bees while underwater.
1501 if( !u.is_underwater() ) {
1502 const int intensity = cur.get_field_intensity();
1503 // Bees will try to sting you in random body parts, up to 8 times.
1504 for( int i = 0; i < rng( 1, 7 ); i++ ) {
1506 int sum_cover = 0;
1507 for( const item &i : u.worn ) {
1508 if( i.covers( bp->token ) ) {
1509 sum_cover += i.get_coverage();
1510 }
1511 }
1512 // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part]
1513 // AND clothing on affected body part has low environmental protection value
1514 if( ( u.get_armor_cut( bp ) <= 1 || ( sum_cover < 100 && x_in_y( 100 - sum_cover, 100 ) ) ) &&
1515 u.add_env_effect( effect_stung, bp->token, intensity, 9_minutes ) ) {
1516 u.add_msg_if_player( m_bad, _( "The bees sting you in %s!" ),
1517 body_part_name_accusative( bp->token ) );
1518 }
1519 }
1520 }
1521 }
1522 if( ft == fd_incendiary ) {
1523 // Mysterious incendiary substance melts you horribly.
1524 if( u.has_trait( trait_M_SKIN2 ) ||
1525 u.has_trait( trait_M_SKIN3 ) ||
1526 cur.get_field_intensity() == 1 ) {
1527 u.add_msg_player_or_npc( m_bad, _( "The incendiary burns you!" ),
1528 _( "The incendiary burns <npcname>!" ) );
1529 u.hurtall( rng( 1, 3 ), nullptr );
1530 } else {
1531 u.add_msg_player_or_npc( m_bad, _( "The incendiary melts into your skin!" ),
1532 _( "The incendiary melts into <npcname>s skin!" ) );
1533 u.add_effect( effect_onfire, 8_turns, bp_torso );
1534 u.hurtall( rng( 2, 6 ), nullptr );
1535 }
1536 }
1537 // Both gases are unhealthy and become deadly if you cross a related threshold.
1538 if( ft == fd_fungicidal_gas || ft == fd_insecticidal_gas ) {
1539 // The gas won't harm you inside a vehicle.
1540 if( !inside ) {
1541 // Full body suits protect you from the effects of the gas.
1542 if( !( u.worn_with_flag( flag_GAS_PROOF ) && u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
1543 u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
1544 const int intensity = cur.get_field_intensity();
1545 bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes );
1547 ( ft == fd_insecticidal_gas && ( u.get_highest_category() == "INSECT" ||
1548 u.get_highest_category() == "SPIDER" ) ) ) {
1549 inhaled |= u.add_env_effect( effect_badpoison, bp_mouth, 5, intensity * 1_minutes );
1550 u.hurtall( rng( intensity, intensity * 2 ), nullptr );
1551 u.add_msg_if_player( m_bad, _( "The %s burns your skin." ), cur.name() );
1552 }
1553
1554 if( inhaled ) {
1555 u.add_msg_if_player( m_bad, _( "The %s makes you feel sick." ), cur.name() );
1556 }
1557 }
1558 }
1559 }
1560 }
1561}
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:331
@ bp_foot_l
Definition: bodypart.h:52
@ bp_leg_r
Definition: bodypart.h:51
@ bp_eyes
Definition: bodypart.h:44
@ bp_hand_l
Definition: bodypart.h:48
@ bp_arm_l
Definition: bodypart.h:46
@ bp_leg_l
Definition: bodypart.h:50
@ bp_hand_r
Definition: bodypart.h:49
@ bp_head
Definition: bodypart.h:43
@ bp_torso
Definition: bodypart.h:42
@ bp_mouth
Definition: bodypart.h:45
@ bp_foot_r
Definition: bodypart.h:53
@ bp_arm_r
Definition: bodypart.h:47
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: character.cpp:765
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6124
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3265
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:898
std::list< item > worn
Definition: character.h:1569
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:7026
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1221
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6869
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7841
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3235
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8664
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1601
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6481
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1825
bodypart_id get_random_body_part(bool main=false) const
Definition: creature.cpp:1667
virtual bool is_underwater() const
Definition: creature.cpp:172
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1674
int extra_radiation_min() const
Definition: field.cpp:14
int radiation_hurt_damage_min() const
Definition: field.cpp:24
std::string radiation_hurt_message() const
Definition: field.cpp:34
int extra_radiation_max() const
Definition: field.cpp:19
std::string name() const
Definition: field.h:84
int radiation_hurt_damage_max() const
Definition: field.cpp:29
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5926
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:747
int burn_body_part(player &u, field_entry &cur, body_part bp, int scale)
Definition: map_field.cpp:125
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:367
bool is_player() const override
Definition: player.h:93
field_type_id fd_bees
Definition: field_type.cpp:371
static const trait_id trait_M_SKIN3("M_SKIN3")
static const std::string flag_GAS_PROOF("GAS_PROOF")
static const efftype_id effect_fungus("fungus")
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const trait_id trait_THRESH_MARLOSS("THRESH_MARLOSS")
static const trait_id trait_WEB_WALKER("WEB_WALKER")
static const efftype_id effect_badpoison("badpoison")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const efftype_id effect_stung("stung")
static const efftype_id effect_poison("poison")
static const efftype_id effect_teargas("teargas")
static const bionic_id bio_heatsink("bio_heatsink")
hp_part
Definition: pldata.h:32
@ num_hp_parts
Definition: pldata.h:39
int type_damage(damage_type dt) const
Definition: damage.cpp:172
#define translate_marker(x)
Marks a string literal to be extracted for translation.
Definition: translations.h:30

References _, Creature::add_effect(), Creature::add_env_effect(), add_msg(), player::add_msg_if_player(), player::add_msg_player_or_npc(), bio_heatsink, body_part_name_accusative(), bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, burn_body_part(), Creature::check_dead_state(), convert_bp(), item::covers(), Character::deal_damage(), DT_ELECTRIC, DT_HEAT, effect_badpoison, effect_blind, effect_fungus, effect_onfire, effect_poison, effect_stung, effect_teargas, effect_webbed, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_sap, fd_shock_vent, fd_sludge, fd_tear_gas, fd_web, flag_GAS_PROOF(), Creature::get_all_body_parts(), Character::get_armor_cut(), item::get_coverage(), Character::get_env_resist(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), Character::get_highest_category(), Creature::get_random_body_part(), Character::has_active_bionic(), Character::has_trait(), Character::has_two_arms(), Character::hp_to_bp(), Character::hurtall(), string_id< T >::id(), Character::in_vehicle, Character::irradiate(), Character::is_elec_immune(), field_entry::is_field_alive(), Character::is_on_ground(), player::is_player(), Creature::is_underwater(), Character::is_wearing(), itype_rm13_armor_on, m_bad, m_warning, Character::mod_pain(), Creature::moves, field_entry::name(), num_bp, num_hp_parts, one_in(), Character::pos(), field_entry::radiation_hurt_damage_max(), field_entry::radiation_hurt_damage_min(), field_entry::radiation_hurt_message(), rng(), field_entry::set_field_intensity(), teleport::teleport(), dealt_damage_instance::total_damage(), trait_ACIDPROOF, trait_ELECTRORECEPTORS, trait_M_IMMUNE, trait_M_SKIN2, trait_M_SKIN3, trait_THRESH_MARLOSS, trait_THRESH_MYCUS, trait_WEB_WALKER, translate_marker, dealt_damage_instance::type_damage(), veh_at(), Character::worn, Character::worn_with_flag(), and x_in_y().

Referenced by creature_in_field().

◆ point_within_camp()

bool map::point_within_camp ( const tripoint point_check) const

Definition at line 5693 of file map.cpp.

5694{
5695 // TODO: fix point types
5696 const tripoint_abs_omt omt_check( ms_to_omt_copy( point_check ) );
5697 const point_abs_omt p = omt_check.xy();
5698 for( int x2 = -2; x2 < 2; x2++ ) {
5699 for( int y2 = -2; y2 < 2; y2++ ) {
5700 if( std::optional<basecamp *> bcp = overmap_buffer.find_camp( p + point( x2, y2 ) ) ) {
5701 return ( *bcp )->camp_omt_pos().z() == point_check.z;
5702 }
5703 }
5704 }
5705 return false;
5706}
constexpr auto xy() const
Definition: coordinates.h:130
std::optional< basecamp * > find_camp(const point_abs_omt &p)

References overmapbuffer::find_camp(), ms_to_omt_copy(), overmap_buffer, coords::coord_point< Point, Origin, Scale >::xy(), and tripoint::z.

◆ points_in_radius()

tripoint_range< tripoint > map::points_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
) const

Definition at line 8762 of file map.cpp.

8764{
8765 const tripoint min( std::max<int>( 0, center.x - radius ), std::max<int>( 0, center.y - radius ),
8766 clamp<int>( center.z - radiusz, -OVERMAP_DEPTH, OVERMAP_HEIGHT ) );
8767 const tripoint max( std::min<int>( SEEX * my_MAPSIZE - 1, center.x + radius ),
8768 std::min<int>( SEEX * my_MAPSIZE - 1, center.y + radius ), clamp<int>( center.z + radiusz,
8770 return tripoint_range<tripoint>( min, max );
8771}

References center, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, and SEEX.

Referenced by add_splash(), bash_furn_success(), climb_difficulty(), collapse_at(), collapse_check(), game::control_vehicle(), displace_water(), computer_session::failure_manhacks(), computer_session::failure_secubots(), find_furnitures_or_vparts_with_flag_in_radius(), find_furnitures_with_flag_in_radius(), find_potential_computer_point(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), get_creatures_in_radius(), has_adjacent_furniture_with(), has_nearby_chair(), has_nearby_fire(), has_nearby_table(), is_cornerfloor(), is_wall_adjacent(), map_funcs::migo_nerve_cage_removal(), game::monmove(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), trap::on_disarmed(), game::place_critter_around(), mission_start::place_deposit_box(), game::place_player(), place_vending(), game::process_artifact(), process_fields_in_submap(), propagate_suspension_check(), avatar_action::ramp_move(), reachable_flood_steps(), spawn_monsters_submap(), spread_gas(), use_amount(), and game::vertical_move().

◆ points_in_rectangle()

tripoint_range< tripoint > map::points_in_rectangle ( const tripoint from,
const tripoint to 
) const

Definition at line 8752 of file map.cpp.

8753{
8754 const tripoint min( std::max( 0, std::min( from.x, to.x ) ), std::max( 0, std::min( from.y,
8755 to.y ) ), std::max( -OVERMAP_DEPTH, std::min( from.z, to.z ) ) );
8756 const tripoint max( std::min( SEEX * my_MAPSIZE - 1, std::max( from.x, to.x ) ),
8757 std::min( SEEX * my_MAPSIZE - 1, std::max( from.y, to.y ) ), std::min( OVERMAP_HEIGHT,
8758 std::max( from.z, to.z ) ) );
8759 return tripoint_range<tripoint>( min, max );
8760}

References my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_faction_ownership(), debug_menu::debug(), draw_lab(), draw_mine(), farm_action(), game::find_or_make_stairs(), generate_lightmap(), jmapgen_setmap::has_vehicle_collision(), avatar_action::move(), MapExtras::mx_portal(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), and om_harvest_ter().

◆ points_on_zlevel() [1/2]

◆ points_on_zlevel() [2/2]

tripoint_range< tripoint > map::points_on_zlevel ( int  z) const

Same as above, but uses the specific z-level.

If the given z-level is invalid, it returns an empty range.

Definition at line 8773 of file map.cpp.

8774{
8775 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
8776 // TODO: need a default constructor that creates an empty range.
8778 }
8780 tripoint( 0, 0, z ), tripoint( SEEX * my_MAPSIZE - 1, SEEY * my_MAPSIZE - 1, z ) );
8781}

References my_MAPSIZE, OVERMAP_HEIGHT, SEEX, SEEY, tripoint_above, and tripoint_zero.

◆ process_falling()

void map::process_falling ( )

Invoked drop_everything on cached dirty tiles.

Definition at line 2356 of file map.cpp.

2357{
2358 if( !zlevels ) {
2359 support_cache_dirty.clear();
2360 return;
2361 }
2362
2363 if( !support_cache_dirty.empty() ) {
2364 add_msg( m_debug, "Checking %d tiles for falling objects",
2365 support_cache_dirty.size() );
2366 // We want the cache to stay constant, but falling can change it
2367 std::set<tripoint> last_cache = std::move( support_cache_dirty );
2368 support_cache_dirty.clear();
2369 for( const tripoint &p : last_cache ) {
2370 drop_everything( p );
2371 }
2372 }
2373}
void drop_everything(const tripoint &p)
Handles map objects of given type (not creatures) falling down.
Definition: map.cpp:2127
std::set< tripoint > support_cache_dirty
Definition: map.h:1499

References add_msg(), drop_everything(), m_debug, avatar_action::move(), support_cache_dirty, and zlevels.

Referenced by game::do_turn().

◆ process_fields()

void map::process_fields ( )

Definition at line 142 of file map_field.cpp.

143{
144 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
145 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
146 for( int z = minz; z <= maxz; z++ ) {
147 auto &field_cache = get_cache( z ).field_cache;
148 for( int x = 0; x < my_MAPSIZE; x++ ) {
149 for( int y = 0; y < my_MAPSIZE; y++ ) {
150 if( field_cache[ x + y * MAPSIZE ] ) {
151 submap *const current_submap = get_submap_at_grid( { x, y, z } );
152 process_fields_in_submap( current_submap, tripoint( x, y, z ) );
153 }
154 }
155 }
156
157 // no need to invalidate "transparency" and "seen" caches here
158 // they are invalidated point by point inside the `process_fields_in_submap`
159 }
160}
void process_fields_in_submap(submap *current_submap, const tripoint &submap_pos)
Definition: map_field.cpp:397

References abs_sub, level_cache::field_cache, get_cache(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, process_fields_in_submap(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_fields_in_submap()

void map::process_fields_in_submap ( submap current_submap,
const tripoint submap_pos 
)

Definition at line 397 of file map_field.cpp.

399{
400 scent_block sblk( submap, g->scent );
401
402 // Holds m.field_at(x,y).find_field(fd_some_field) type returns.
403 // Just to avoid typing that long string for a temp value.
404 field_entry *tmpfld = nullptr;
405
406 map &here = get_map();
407 tripoint thep;
408 thep.z = submap.z;
409
410 // Initialize the map tile wrapper
411 maptile map_tile( current_submap, point_zero );
412 int &locx = map_tile.pos_.x;
413 int &locy = map_tile.pos_.y;
414 const point sm_offset( submap.x * SEEX, submap.y * SEEY );
415
416 // Loop through all tiles in this submap indicated by current_submap
417 for( locx = 0; locx < SEEX; locx++ ) {
418 for( locy = 0; locy < SEEY; locy++ ) {
419 // Get a reference to the field variable from the submap;
420 // contains all the pointers to the real field effects.
421 field &curfield = current_submap->get_field( { static_cast<int>( locx ), static_cast<int>( locy ) } );
422
423 // when displayed_field_type == fd_null it means that `curfield` has no fields inside
424 // avoids instantiating (relatively) expensive map iterator
425 if( !curfield.displayed_field_type() ) {
426 continue;
427 }
428
429 // This is a translation from local coordinates to submap coordinates.
430 // All submaps are in one long 1d array.
431 thep.x = locx + sm_offset.x;
432 thep.y = locy + sm_offset.y;
433 // A const reference to the tripoint above, so that the code below doesn't accidentally change it
434 const tripoint &p = thep;
435
436 // This should be true only when the field in the current tile changes transparency state,
437 // More correctly: not just when the field is opaque, but when it changes state
438 // to a more/less transparent one
439 bool dirty_transparency_cache = false;
440
441 for( auto it = curfield.begin(); it != curfield.end(); ) {
442 // Iterating through all field effects in the submap's field.
443 field_entry &cur = it->second;
444
445 // Holds cur.get_field_type() as that is what the old system used before rewrite.
446 field_type_id cur_fd_type_id = cur.get_field_type();
447
448 // The field might have been killed by processing a neighbor field
449 if( !cur.is_field_alive() ) {
450 if( !cur_fd_type_id->get_transparent( cur.get_field_intensity() - 1 ) ) {
451 dirty_transparency_cache = true;
452 }
453 --current_submap->field_count;
454 curfield.remove_field( it++ );
455 continue;
456 }
457
458 // Again, legacy support in the event someone Mods set_field_intensity to allow more values.
459 if( cur.get_field_intensity() > 3 || cur.get_field_intensity() < 1 ) {
460 // TODO: Remove this eventually as we would suppoort more than 3 field intensity levels
461 debugmsg( "Whoooooa intensity of %d", cur.get_field_intensity() );
462 }
463
464 dirty_transparency_cache |= cur_fd_type_id->dirty_transparency_cache;
465
466 // Don't process "newborn" fields. This gives the player time to run if they need to.
467 if( cur.get_field_age() == 0_turns ) {
468 cur_fd_type_id = fd_null;
469 }
470
471 const field_type &cur_fd_type = *cur_fd_type_id;
472
473 // Upgrade field intensity
474 if( cur.intensity_upgrade_chance() > 0 &&
476 cur.intensity_upgrade_duration() > 0_turns &&
479 }
480
481 int part;
482 const ter_t &ter = map_tile.get_ter_t();
483 // Dissipate faster in water
484 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
486 }
487 if( cur_fd_type_id == fd_acid ) {
488 // Try to fall by a z-level
489 if( zlevels && p.z > -OVERMAP_DEPTH ) {
490 tripoint dst{ p.xy(), p.z - 1 };
491 if( valid_move( p, dst, true, true ) ) {
492 field_entry *acid_there = field_at( dst ).find_field( fd_acid );
493 if( acid_there == nullptr ) {
495 } else {
496 // Math can be a bit off,
497 // but "boiling" falling acid can be allowed to be stronger
498 // than acid that just lies there
499 const int sum_intensity = cur.get_field_intensity() + acid_there->get_field_intensity();
500 const int new_intensity = std::min( 3, sum_intensity );
501 // No way to get precise elapsed time, let's always reset
502 // Allow falling acid to last longer than regular acid to show it off
503 const time_duration new_age = -1_minutes * ( sum_intensity - new_intensity );
504 acid_there->set_field_intensity( new_intensity );
505 acid_there->set_field_age( new_age );
506 }
507
508 // Set ourselves up for removal
509 cur.set_field_intensity( 0 );
510 }
511 }
512 // TODO: Allow spreading to the sides if age < 0 && intensity == 3
513 }
514 if( cur_fd_type.apply_slime_factor > 0 ) {
515 sblk.apply_slime( p, cur.get_field_intensity() * cur_fd_type.apply_slime_factor );
516 }
517 if( cur_fd_type_id == fd_fire ) {
518 cur.set_field_age( std::max( -24_hours, cur.get_field_age() ) );
519 // Entire objects for ter/frn for flags
520 const ter_t &ter = map_tile.get_ter_t();
521 const furn_t &frn = map_tile.get_furn_t();
522
523 // We've got ter/furn cached, so let's use that
524 const bool is_sealed = ter_furn_has_flag( ter, frn, TFLAG_SEALED ) &&
526 // Consumed items count
527 int consumed = 0;
528 // How much time to add to the fire's life due to burned items/terrain/furniture
529 time_duration time_added = 0_turns;
530 // Checks if the fire can spread
531 const bool can_spread = !ter_furn_has_flag( ter, frn, TFLAG_FIRE_CONTAINER );
532 const bool no_floor = ter.has_flag( TFLAG_NO_FLOOR );
533 // If the flames are in furniture with fire_container flag like brazier or oven,
534 // they're fully contained, so skip consuming terrain
535 const bool can_burn = !no_floor && can_spread &&
536 ( check_flammable( ter ) || check_flammable( frn ) );
537 // The huge indent below should probably be somehow moved away from here
538 // without forcing the function to use i_at( p ) for fires without items
539 if( !is_sealed && map_tile.get_item_count() > 0 ) {
540 map_stack items_here = i_at( p );
541 std::vector<item> new_content;
542 for( auto explosive = items_here.begin(); explosive != items_here.end(); ) {
543 if( explosive->will_explode_in_fire() ) {
544 // We need to make a copy because the iterator validity is not predictable
545 item copy = *explosive;
546 explosive = items_here.erase( explosive );
547 if( copy.detonate( p, new_content ) ) {
548 // Need to restart, iterators may not be valid
549 explosive = items_here.begin();
550 }
551 } else {
552 ++explosive;
553 }
554 }
555
556 fire_data frd( cur.get_field_intensity(), !can_spread );
557 // The highest # of items this fire can remove in one turn
558 int max_consume = cur.get_field_intensity() * 2;
559
560 for( auto fuel = items_here.begin(); fuel != items_here.end() && consumed < max_consume; ) {
561 // `item::burn` modifies the charges in order to simulate some of them getting
562 // destroyed by the fire, this changes the item weight, but may not actually
563 // destroy it. We need to spawn products anyway.
564 const units::mass old_weight = fuel->weight( false );
565 bool destroyed = fuel->burn( frd );
566 // If the item is considered destroyed, it may have negative charge count,
567 // see `item::burn?. This in turn means `item::weight` returns a negative value,
568 // which we can not use, so only call `weight` when it's still an existing item.
569 const units::mass new_weight = destroyed ? 0_gram : fuel->weight( false );
570 if( old_weight != new_weight ) {
571 create_burnproducts( p, *fuel, old_weight - new_weight );
572 }
573
574 if( destroyed ) {
575 // If we decided the item was destroyed by fire, remove it.
576 // But remember its contents, except for irremovable mods, if any
577 const std::list<item *> content_list = fuel->contents.all_items_top();
578 for( item *it : content_list ) {
579 if( !it->is_irremovable() ) {
580 new_content.push_back( item( *it ) );
581 }
582 }
583 fuel = items_here.erase( fuel );
584 consumed++;
585 } else {
586 ++fuel;
587 }
588 }
589
590 spawn_items( p, new_content );
591 time_added = 1_turns * roll_remainder( frd.fuel_produced );
592 }
593
594 // Get the part of the vehicle in the fire (_internal skips the boundary check)
595 vehicle *veh = veh_at_internal( p, part );
596 if( veh != nullptr ) {
597 veh->damage( part, cur.get_field_intensity() * 10, DT_HEAT, true );
598 // Damage the vehicle in the fire.
599 }
600 if( can_burn ) {
601 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
602 // Flames die quickly on water
603 cur.set_field_age( cur.get_field_age() + 4_minutes );
604 }
605
606 // Consume the terrain we're on
607 if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE ) ) {
608 // The fire feeds on the ground itself until max intensity.
609 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
610 if( cur.get_field_intensity() > 1 &&
611 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
612 destroy( p, false );
613 }
614
615 } else if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE_HARD ) &&
616 one_in( 3 ) ) {
617 // The fire feeds on the ground itself until max intensity.
618 time_added += 1_turns * ( 4 - cur.get_field_intensity() );
619 if( cur.get_field_intensity() > 1 &&
620 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
621 destroy( p, false );
622 }
623
624 } else if( ter.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
625 // The fire feeds on the ground itself until max intensity.
626 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
627 if( cur.get_field_intensity() > 1 &&
628 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
629 if( p.z > 0 ) {
630 // We're in the air
631 ter_set( p, t_open_air );
632 } else {
633 ter_set( p, t_dirt );
634 }
635 }
636
637 } else if( frn.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
638 // The fire feeds on the ground itself until max intensity.
639 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
640 if( cur.get_field_intensity() > 1 &&
641 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
642 furn_set( p, f_ash );
643 }
644
645 }
646 }
647
648 if( ter.has_flag( TFLAG_NO_FLOOR ) && zlevels && p.z > -OVERMAP_DEPTH ) {
649 // We're hanging in the air - let's fall down
650 tripoint dst{ p.xy(), p.z - 1 };
651 if( valid_move( p, dst, true, true ) ) {
652 maptile dst_tile = maptile_at_internal( dst );
653 field_entry *fire_there = dst_tile.find_field( fd_fire );
654 if( fire_there == nullptr ) {
655 add_field( dst, fd_fire, 1, 0_turns, false );
657 } else {
658 // Don't fuel raging fires or they'll burn forever
659 // as they can produce small fires above themselves
660 int new_intensity = std::max( cur.get_field_intensity(),
661 fire_there->get_field_intensity() );
662 // Allow smaller fires to combine
663 if( new_intensity < 3 &&
664 cur.get_field_intensity() == fire_there->get_field_intensity() ) {
665 new_intensity++;
666 }
667 // A raging fire below us can support us for a while
668 // Otherwise decay and decay fast
669 if( fire_there->get_field_intensity() < 3 || one_in( 10 ) ) {
671 }
672 fire_there->set_field_intensity( new_intensity );
673 }
674 break;
675 }
676 }
677 // Lower age is a longer lasting fire
678 if( time_added != 0_turns ) {
679 cur.set_field_age( cur.get_field_age() - time_added );
680 } else if( can_burn ) {
681 // Nothing to burn = fire should be dying out faster
682 // Drain more power from big fires, so that they stop raging over nothing
683 // Except for fires on stoves and fireplaces, those are made to keep the fire alive
684 cur.mod_field_age( 10_seconds * cur.get_field_intensity() );
685 }
686
687 // Allow raging fires (and only raging fires) to spread up
688 // Spreading down is achieved by wrecking the walls/floor and then falling
689 if( zlevels && cur.get_field_intensity() == 3 && p.z < OVERMAP_HEIGHT ) {
690 const tripoint dst_p = tripoint( p.xy(), p.z + 1 );
691 // Let it burn through the floor
692 maptile dst = maptile_at_internal( dst_p );
693 const auto &dst_ter = dst.get_ter_t();
694 if( dst_ter.has_flag( TFLAG_NO_FLOOR ) ||
695 dst_ter.has_flag( TFLAG_FLAMMABLE ) ||
696 dst_ter.has_flag( TFLAG_FLAMMABLE_ASH ) ||
697 dst_ter.has_flag( TFLAG_FLAMMABLE_HARD ) ) {
698 field_entry *nearfire = dst.find_field( fd_fire );
699 if( nearfire != nullptr ) {
700 nearfire->mod_field_age( -2_turns );
701 } else {
702 add_field( dst_p, fd_fire, 1, 0_turns, false );
703 }
704 // Fueling fires above doesn't cost fuel
705 }
706 }
707
708 // Below we will access our nearest 8 neighbors, so let's cache them now
709 // This should probably be done more globally, because large fires will re-do it a lot
710 auto neighs = get_neighbors( p );
711
712 // If the flames are in a pit, it can't spread to non-pit
713 const bool in_pit = can_spread && ter.id.id() == t_pit;
714
715 // Count adjacent fires, to optimize out needless smoke and hot air
716 int adjacent_fires = 0;
717
718 // If the flames are big, they contribute to adjacent flames
719 if( can_spread ) {
720 if( cur.get_field_intensity() > 1 && one_in( 3 ) ) {
721 // Basically: Scan around for a spot,
722 // if there is more fire there, make it bigger and give it some fuel.
723 // This is how big fires spend their excess age:
724 // making other fires bigger. Flashpoint.
725 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
726 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
727 count != neighs.size() && cur.get_field_age() < 0_turns;
728 i = ( i + 1 ) % neighs.size(), count++ ) {
729 maptile &dst = neighs[i].second;
730 auto dstfld = dst.find_field( fd_fire );
731 // If the fire exists and is weaker than ours, boost it
732 if( dstfld != nullptr &&
733 ( dstfld->get_field_intensity() <= cur.get_field_intensity() ||
734 dstfld->get_field_age() > cur.get_field_age() ) &&
735 ( in_pit == ( dst.get_ter() == t_pit ) ) ) {
736 if( dstfld->get_field_intensity() < 2 ) {
737 dstfld->set_field_intensity( dstfld->get_field_intensity() + 1 );
738 }
739
740 dstfld->set_field_age( dstfld->get_field_age() - 5_minutes );
741 cur.set_field_age( cur.get_field_age() + 5_minutes );
742 }
743 if( dstfld != nullptr ) {
744 adjacent_fires++;
745 }
746 }
747 } else if( cur.get_field_age() < 0_turns && cur.get_field_intensity() < 3 ) {
748 // See if we can grow into a stage 2/3 fire, for this
749 // burning neighbors are necessary in addition to
750 // field age < 0, or alternatively, a LOT of fuel.
751
752 // The maximum fire intensity is 1 for a lone fire, 2 for at least 1 neighbor,
753 // 3 for at least 2 neighbors.
754 int maximum_intensity = 1;
755
756 // The following logic looks a bit complex due to optimization concerns, so here are the semantics:
757 // 1. Calculate maximum field intensity based on fuel, -50 minutes is 2(medium), -500 minutes is 3(raging)
758 // 2. Calculate maximum field intensity based on neighbors, 3 neighbors is 2(medium), 7 or more neighbors is 3(raging)
759 // 3. Pick the higher maximum between 1. and 2.
760 if( cur.get_field_age() < -500_minutes ) {
761 maximum_intensity = 3;
762 } else {
763 for( auto &neigh : neighs ) {
764 if( neigh.second.get_field().find_field( fd_fire ) != nullptr ) {
765 adjacent_fires++;
766 }
767 }
768 maximum_intensity = 1 + ( adjacent_fires >= 3 ) + ( adjacent_fires >= 7 );
769
770 if( maximum_intensity < 2 && cur.get_field_age() < -50_minutes ) {
771 maximum_intensity = 2;
772 }
773 }
774
775 // If we consumed a lot, the flames grow higher
776 if( cur.get_field_intensity() < maximum_intensity && cur.get_field_age() < 0_turns ) {
777 // Fires under 0 age grow in size. Level 3 fires under 0 spread later on.
778 // Weaken the newly-grown fire
780 cur.set_field_age( cur.get_field_age() + 10_minutes * cur.get_field_intensity() );
781 }
782 }
783
784 // Consume adjacent fuel / terrain / webs to spread.
785 // Our iterator will start at end_i + 1 and increment from there and then wrap around.
786 // This guarantees it will check all neighbors, starting from a random one
787 const size_t end_i = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
788 for( size_t i = ( end_i + 1 ) % neighs.size(), count = 0;
789 count != neighs.size();
790 i = ( i + 1 ) % neighs.size(), count++ ) {
791 if( one_in( cur.get_field_intensity() * 2 ) ) {
792 // Skip some processing to save on CPU
793 continue;
794 }
795
796 tripoint &dst_p = neighs[i].first;
797 maptile &dst = neighs[i].second;
798 // No bounds checking here: we'll treat the invalid neighbors as valid.
799 // We're using the map tile wrapper, so we can treat invalid tiles as sentinels.
800 // This will create small oddities on map edges, but nothing more noticeable than
801 // "cut-off" that happens with bounds checks.
802
803 field_entry *nearfire = dst.find_field( fd_fire );
804 if( nearfire != nullptr ) {
805 // We handled supporting fires in the section above, no need to do it here
806 continue;
807 }
808
809 field_entry *nearwebfld = dst.find_field( fd_web );
810 int spread_chance = 25 * ( cur.get_field_intensity() - 1 );
811 if( nearwebfld != nullptr ) {
812 spread_chance = 50 + spread_chance / 2;
813 }
814
815 const ter_t &dster = dst.get_ter_t();
816 const furn_t &dsfrn = dst.get_furn_t();
817 // Allow weaker fires to spread occasionally
818 const int power = cur.get_field_intensity() + one_in( 5 );
819 if( can_spread && rng( 1, 100 ) < spread_chance &&
820 ( check_flammable( dster ) || check_flammable( dsfrn ) ) &&
821 ( in_pit == ( dster.id.id() == t_pit ) ) &&
822 (
823 ( power >= 3 && cur.get_field_age() < 0_turns && one_in( 20 ) ) ||
824 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE ) && one_in( 2 ) ) ) ||
825 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_ASH ) && one_in( 2 ) ) ) ||
826 ( power >= 3 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_HARD ) && one_in( 5 ) ) ) ||
827 nearwebfld || ( dst.get_item_count() > 0 &&
829 one_in( 5 ) )
830 ) ) {
831 // Nearby open flammable ground? Set it on fire.
832 add_field( dst_p, fd_fire, 1, 0_turns, false );
833 tmpfld = dst.find_field( fd_fire );
834 if( tmpfld != nullptr ) {
835 // Make the new fire quite weak, so that it doesn't start jumping around instantly
836 tmpfld->set_field_age( 2_minutes );
837 // Consume a bit of our fuel
838 cur.set_field_age( cur.get_field_age() + 1_minutes );
839 }
840 if( nearwebfld ) {
841 nearwebfld->set_field_intensity( 0 );
842 }
843 }
844 }
845 }
846 }
847
848 // Spread gaseous fields
849 if( cur.gas_can_spread() ) {
850 const int gas_percent_spread = cur_fd_type.percent_spread;
851 if( gas_percent_spread > 0 ) {
852 const time_duration outdoor_age_speedup = cur_fd_type.outdoor_age_speedup;
853 spread_gas( cur, p, gas_percent_spread, outdoor_age_speedup, sblk );
854 }
855 }
856
857 if( cur_fd_type_id == fd_fungal_haze ) {
858 if( one_in( 10 - 2 * cur.get_field_intensity() ) ) {
859 // Haze'd terrain
861 }
862 }
863
864 // Process npc complaints
865 const std::tuple<int, std::string, time_duration, std::string> &npc_complain_data =
866 cur_fd_type.npc_complain_data;
867 const int chance = std::get<0>( npc_complain_data );
868 if( chance > 0 && one_in( chance ) ) {
869 if( npc *const np = g->critter_at<npc>( p, false ) ) {
870 np->complain_about( std::get<1>( npc_complain_data ),
871 std::get<2>( npc_complain_data ),
872 std::get<3>( npc_complain_data ) );
873 }
874 }
875
876 // Apply radiation
877 if( cur.extra_radiation_max() > 0 ) {
878 int extra_radiation = rng( cur.extra_radiation_min(), cur.extra_radiation_max() );
879 adjust_radiation( p, extra_radiation );
880 }
881
882 // Apply wandering fields from vents
883 if( cur_fd_type.wandering_field ) {
884 for( const tripoint &pnt : points_in_radius( p, cur.get_field_intensity() - 1 ) ) {
885 field &wandering_field = get_field( pnt );
886 tmpfld = wandering_field.find_field( cur_fd_type.wandering_field );
887 if( tmpfld && tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
888 tmpfld->set_field_intensity( tmpfld->get_field_intensity() + 1 );
889 } else {
890 add_field( pnt, cur_fd_type.wandering_field, cur.get_field_intensity() );
891 }
892 }
893 }
894
895 if( cur_fd_type_id == fd_fire_vent ) {
896
897 if( cur.get_field_intensity() > 1 ) {
898 if( one_in( 3 ) ) {
900 }
902 } else {
903 dirty_transparency_cache = true;
904 add_field( p, fd_flame_burst, 3, cur.get_field_age() );
905 cur.set_field_intensity( 0 );
906 }
907 }
908 if( cur_fd_type_id == fd_flame_burst ) {
909 if( cur.get_field_intensity() > 1 ) {
912 } else {
913 dirty_transparency_cache = true;
914 add_field( p, fd_fire_vent, 3, cur.get_field_age() );
915 cur.set_field_intensity( 0 );
916 }
917 }
918 if( cur_fd_type_id == fd_electricity ) {
919 // 4 in 5 chance to spread
920 if( !one_in( 5 ) ) {
921 std::vector<tripoint> valid;
922 // We're grounded
923 if( impassable( p ) && cur.get_field_intensity() > 1 ) {
924 int tries = 0;
925 tripoint pnt;
926 pnt.z = p.z;
927 while( tries < 10 && cur.get_field_age() < 5_minutes && cur.get_field_intensity() > 1 ) {
928 pnt.x = p.x + rng( -1, 1 );
929 pnt.y = p.y + rng( -1, 1 );
930 if( passable( pnt ) && !obstructed_by_vehicle_rotation( p, pnt ) ) {
931 add_field( pnt, fd_electricity, 1, cur.get_field_age() + 1_turns );
933 tries = 0;
934 } else {
935 tries++;
936 }
937 }
938 // We're not grounded; attempt to ground
939 } else {
940 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
941 // Grounded tiles first
942 if( impassable( dst ) ) {
943 valid.push_back( dst );
944 }
945 }
946 // Spread to adjacent space, then
947 if( valid.empty() ) {
948 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
949 field_entry *elec = get_field( dst ).find_field( fd_electricity );
950 bool pass = passable( dst ) && !obstructed_by_vehicle_rotation( p, dst );
951 if( pass && elec != nullptr &&
952 elec->get_field_intensity() < 3 ) {
953 elec->set_field_intensity( elec->get_field_intensity() + 1 );
955 } else if( pass ) {
956 add_field( dst, fd_electricity, 1, cur.get_field_age() + 1_turns );
957 }
959 }
960 while( !valid.empty() && cur.get_field_intensity() > 1 ) {
961 const tripoint target = random_entry_removed( valid );
962 add_field( target, fd_electricity, 1, cur.get_field_age() + 1_turns );
964 }
965 }
966 }
967 }
968
969 int monster_spawn_chance = cur.monster_spawn_chance();
970 int monster_spawn_count = cur.monster_spawn_count();
971 if( monster_spawn_count > 0 && monster_spawn_chance > 0 && one_in( monster_spawn_chance ) ) {
972 for( ; monster_spawn_count > 0; monster_spawn_count-- ) {
974 cur.monster_spawn_group(), &monster_spawn_count );
975 if( !spawn_details.name ) {
976 continue;
977 }
978 if( const std::optional<tripoint> spawn_point = random_point(
980 [this]( const tripoint & n ) {
981 return passable( n );
982 } ) ) {
983 add_spawn( spawn_details.name, spawn_details.pack_size, *spawn_point );
984 }
985 }
986 }
987
988 if( cur_fd_type_id == fd_push_items ) {
989 map_stack items = i_at( p );
990 for( auto pushee = items.begin(); pushee != items.end(); ) {
991 if( pushee->typeId() != itype_rock ||
992 pushee->age() < 1_turns ) {
993 pushee++;
994 } else {
995 item tmp = *pushee;
996 tmp.set_age( 0_turns );
997 pushee = items.erase( pushee );
998 std::vector<tripoint> valid;
999 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
1000 if( get_field( dst, fd_push_items ) != nullptr ) {
1001 valid.push_back( dst );
1002 }
1003 }
1004 if( !valid.empty() ) {
1005 tripoint newp = random_entry( valid );
1006 add_item_or_charges( newp, tmp );
1007 if( g->u.pos() == newp ) {
1008 add_msg( m_bad, _( "A %s hits you!" ), tmp.tname() );
1009 const bodypart_id hit = g->u.get_random_body_part();
1010 g->u.deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1011 g->u.check_dead_state();
1012 }
1013
1014 if( npc *const p = g->critter_at<npc>( newp ) ) {
1015 // TODO: combine with player character code above
1016 const bodypart_id hit = g->u.get_random_body_part();
1017 p->deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1018 if( g->u.sees( newp ) ) {
1019 add_msg( _( "A %1$s hits %2$s!" ), tmp.tname(), p->name );
1020 }
1021 p->check_dead_state();
1022 } else if( monster *const mon = g->critter_at<monster>( newp ) ) {
1023 mon->apply_damage( nullptr, bodypart_id( "torso" ),
1024 6 - mon->get_armor_bash( bodypart_id( "torso" ) ) );
1025 if( g->u.sees( newp ) ) {
1026 add_msg( _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() );
1027 }
1028 mon->check_dead_state();
1029 }
1030 }
1031 }
1032 }
1033 }
1034 if( cur_fd_type_id == fd_shock_vent ) {
1035 if( cur.get_field_intensity() > 1 ) {
1036 if( one_in( 5 ) ) {
1038 }
1039 } else {
1040 cur.set_field_intensity( 3 );
1041 int num_bolts = rng( 3, 6 );
1042 for( int i = 0; i < num_bolts; i++ ) {
1043 int xdir = 0;
1044 int ydir = 0;
1045 while( xdir == 0 && ydir == 0 ) {
1046 xdir = rng( -1, 1 );
1047 ydir = rng( -1, 1 );
1048 }
1049 int dist = rng( 4, 12 );
1050 int boltx = p.x;
1051 int bolty = p.y;
1052 for( int n = 0; n < dist; n++ ) {
1053 boltx += xdir;
1054 bolty += ydir;
1055 add_field( tripoint( boltx, bolty, p.z ), fd_electricity, rng( 2, 3 ) );
1056 if( one_in( 4 ) ) {
1057 if( xdir == 0 ) {
1058 xdir = rng( 0, 1 ) * 2 - 1;
1059 } else {
1060 xdir = 0;
1061 }
1062 }
1063 if( one_in( 4 ) ) {
1064 if( ydir == 0 ) {
1065 ydir = rng( 0, 1 ) * 2 - 1;
1066 } else {
1067 ydir = 0;
1068 }
1069 }
1070 }
1071 }
1072 }
1073 }
1074 if( cur_fd_type_id == fd_acid_vent ) {
1075
1076 if( cur.get_field_intensity() > 1 ) {
1077 if( cur.get_field_age() >= 1_minutes ) {
1079 cur.set_field_age( 0_turns );
1080 }
1081 } else {
1082 cur.set_field_intensity( 3 );
1083 for( const tripoint &t : points_in_radius( p, 5 ) ) {
1084 const field_entry *acid = get_field( t, fd_acid );
1085 if( acid != nullptr && acid->get_field_intensity() == 0 ) {
1086 int new_intensity = 3 - rl_dist( p, t ) / 2 + ( one_in( 3 ) ? 1 : 0 );
1087 if( new_intensity > 3 ) {
1088 new_intensity = 3;
1089 }
1090 if( new_intensity > 0 ) {
1091 add_field( t, fd_acid, new_intensity );
1092 }
1093 }
1094 }
1095 }
1096 }
1097 if( cur_fd_type_id == fd_bees ) {
1098 // Poor bees are vulnerable to so many other fields.
1099 // TODO: maybe adjust effects based on different fields.
1100 if( curfield.find_field( fd_web ) ||
1101 curfield.find_field( fd_fire ) ||
1102 curfield.find_field( fd_smoke ) ||
1103 curfield.find_field( fd_toxic_gas ) ||
1104 curfield.find_field( fd_tear_gas ) ||
1105 curfield.find_field( fd_relax_gas ) ||
1106 curfield.find_field( fd_nuke_gas ) ||
1107 curfield.find_field( fd_gas_vent ) ||
1108 curfield.find_field( fd_smoke_vent ) ||
1109 curfield.find_field( fd_fungicidal_gas ) ||
1110 curfield.find_field( fd_insecticidal_gas ) ||
1111 curfield.find_field( fd_fire_vent ) ||
1112 curfield.find_field( fd_flame_burst ) ||
1113 curfield.find_field( fd_electricity ) ||
1114 curfield.find_field( fd_fatigue ) ||
1115 curfield.find_field( fd_shock_vent ) ||
1116 curfield.find_field( fd_plasma ) ||
1117 curfield.find_field( fd_laser ) ||
1118 curfield.find_field( fd_dazzling ) ||
1119 curfield.find_field( fd_electricity ) ||
1120 curfield.find_field( fd_incendiary ) ) {
1121 // Kill them at the end of processing.
1122 cur.set_field_intensity( 0 );
1123 } else {
1124 // Bees chase the player if in range, wander randomly otherwise.
1125 if( !g->u.is_underwater() &&
1126 rl_dist( p, g->u.pos() ) < 10 &&
1127 clear_path( p, g->u.pos(), 10, 1, 100 ) ) {
1128
1129 std::vector<point> candidate_positions =
1130 squares_in_direction( p.xy(), point( g->u.posx(), g->u.posy() ) );
1131 for( point candidate_position : candidate_positions ) {
1132 field &target_field = get_field( tripoint( candidate_position, p.z ) );
1133 // Only shift if there are no bees already there.
1134 // TODO: Figure out a way to merge bee fields without allowing
1135 // Them to effectively move several times in a turn depending
1136 // on iteration direction.
1137 if( !target_field.find_field( fd_bees ) ) {
1138 add_field( tripoint( candidate_position, p.z ), fd_bees,
1139 cur.get_field_intensity(), cur.get_field_age() );
1140 cur.set_field_intensity( 0 );
1141 break;
1142 }
1143 }
1144 } else {
1145 spread_gas( cur, p, 5, 0_turns, sblk );
1146 }
1147 }
1148 }
1149 if( cur_fd_type_id == fd_incendiary ) {
1150 // Needed for variable scope
1151 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
1152 if( has_flag( TFLAG_FLAMMABLE, dst ) ||
1153 has_flag( TFLAG_FLAMMABLE_ASH, dst ) ||
1154 has_flag( TFLAG_FLAMMABLE_HARD, dst ) ) {
1155 add_field( dst, fd_fire, 1 );
1156 }
1157
1158 // Check piles for flammable items and set those on fire
1159 if( flammable_items_at( dst ) ) {
1160 add_field( dst, fd_fire, 1 );
1161 }
1162
1164 }
1165 if( cur_fd_type_id == fd_fungicidal_gas ) {
1166 // Check the terrain and replace it accordingly to simulate the fungus dieing off
1167 const ter_t &ter = map_tile.get_ter_t();
1168 const furn_t &frn = map_tile.get_furn_t();
1169 const int intensity = cur.get_field_intensity();
1170 if( ter.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1171 ter_set( p, t_dirt );
1172 }
1173 if( frn.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1174 furn_set( p, f_null );
1175 }
1176 }
1177
1178 cur.set_field_age( cur.get_field_age() + 1_turns );
1179 auto &fdata = cur.get_field_type().obj();
1180 if( fdata.half_life > 0_turns && cur.get_field_age() > 0_turns &&
1181 dice( 2, to_turns<int>( cur.get_field_age() ) ) > to_turns<int>( fdata.half_life ) ) {
1182 cur.set_field_age( 0_turns );
1184 }
1185 if( !cur.is_field_alive() ) {
1186 --current_submap->field_count;
1187 curfield.remove_field( it++ );
1188 } else {
1189 ++it;
1190 }
1191 }
1192
1193 if( dirty_transparency_cache ) {
1195 set_seen_cache_dirty( thep );
1196 }
1197 }
1198 }
1199 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
1200 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
1201 for( int z = std::max( submap.z - 1, minz ); z <= std::min( submap.z + 1, maxz ); ++z ) {
1202 auto &field_cache = get_cache( z ).field_cache;
1203 for( int y = std::max( submap.y - 1, 0 ); y <= std::min( submap.y + 1, MAPSIZE - 1 ); ++y ) {
1204 for( int x = std::max( submap.x - 1, 0 ); x <= std::min( submap.x + 1, MAPSIZE - 1 ); ++x ) {
1205 if( get_submap_at_grid( { x, y, z } )->field_count > 0 ) {
1206 field_cache.set( x + y * MAPSIZE );
1207 } else {
1208 field_cache.reset( x + y * MAPSIZE );
1209 }
1210 }
1211 }
1212 }
1213 sblk.commit_modifications();
1214}
bool gas_can_spread()
Definition: field.h:93
time_duration intensity_upgrade_duration() const
Definition: field.cpp:44
mongroup_id monster_spawn_group() const
Definition: field.cpp:64
time_duration get_underwater_age_speedup() const
Definition: field.h:97
int monster_spawn_count() const
Definition: field.cpp:54
time_duration mod_field_age(const time_duration &mod_age)
Adds given value to age.
Definition: field.h:73
int intensity_upgrade_chance() const
Definition: field.cpp:39
int monster_spawn_radius() const
Definition: field.cpp:59
int monster_spawn_chance() const
Definition: field.cpp:49
std::map< field_type_id, field_entry >::iterator begin()
Definition: field.cpp:251
std::map< field_type_id, field_entry >::iterator end()
Definition: field.cpp:261
void spread_fungus(const tripoint &p)
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4575
void set_age(const time_duration &age)
Definition: item.cpp:10040
bool detonate(const tripoint &p, std::vector< item > &drops)
Detonates the item and adds remains (if any) to drops.
Definition: item.cpp:8771
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors(const tripoint &p)
Definition: map_field.cpp:191
void create_hot_air(const tripoint &p, int intensity)
Definition: map_field.cpp:364
bool clear_path(const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
Check whether there's a direct line of sight between F and T with the additional movecost restraints.
Definition: map.cpp:6535
void spread_gas(field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
Definition: map_field.cpp:252
void create_burnproducts(const tripoint &p, const item &fuel, const units::mass &burned_mass)
Definition: map_field.cpp:97
field_type_id fd_laser
Definition: field_type.cpp:359
field_type_id fd_plasma
Definition: field_type.cpp:358
field_type_id fd_null
Definition: field_type.cpp:335
std::vector< point > squares_in_direction(point p1, point p2)
Definition: line.cpp:590
static const itype_id itype_rock("rock")
static bool check_flammable(const map_data_common_t &t)
Definition: map_field.cpp:355
static const std::string flag_FUNGUS("FUNGUS")
furn_id f_ash
Definition: mapdata.cpp:1100
ter_id t_pit
Definition: mapdata.cpp:628
@ TFLAG_FLAMMABLE_HARD
Definition: mapdata.h:295
@ TFLAG_FLAMMABLE
Definition: mapdata.h:278
@ TFLAG_FLAMMABLE_ASH
Definition: mapdata.h:290
@ TFLAG_FIRE_CONTAINER
Definition: mapdata.h:294
bool acid(monster *z)
Definition: monattack.cpp:587
int dice(int number, int sides)
Definition: rng.cpp:85
bool get_transparent(int level=0) const
Definition: field_type.h:207
int percent_spread
Definition: field_type.h:158
field_type_id wandering_field
Definition: field_type.h:183
std::tuple< int, std::string, time_duration, std::string > npc_complain_data
Definition: field_type.h:171
time_duration outdoor_age_speedup
Definition: field_type.h:156
int apply_slime_factor
Definition: field_type.h:159
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
size_t get_item_count() const
Definition: submap.h:304
ter_id get_ter() const
Definition: submap.h:260

References _, abs_sub, mattack::acid(), add_field(), add_item_or_charges(), add_msg(), add_spawn(), adjust_radiation(), scent_block::apply_slime(), field_type::apply_slime_factor, field::begin(), item_stack::begin(), check_flammable(), clear_path(), scent_block::commit_modifications(), detail::count(), create_burnproducts(), create_hot_air(), vehicle::damage(), debugmsg, destroy(), destroyed, item::detonate(), dice(), field_type::dirty_transparency_cache, field::displayed_field_type(), DT_BASH, DT_HEAT, eight_horizontal_neighbors, field::end(), item_stack::end(), map_stack::erase(), explosive, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), f_ash, f_null, fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_fire_vent, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_gas_vent, fd_incendiary, fd_insecticidal_gas, fd_laser, fd_nuke_gas, fd_null, fd_plasma, fd_push_items, fd_relax_gas, fd_shock_vent, fd_smoke, fd_smoke_vent, fd_tear_gas, fd_toxic_gas, fd_web, field_at(), level_cache::field_cache, submap::field_count, maptile::find_field(), field::find_field(), flag_FUNGUS(), flammable_items_at(), fire_data::fuel_produced, furn_set(), g, field_entry::gas_can_spread(), get_cache(), get_field(), submap::get_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_item_count(), get_map(), get_neighbors(), get_submap_at_grid(), maptile::get_ter(), maptile::get_ter_t(), field_type::get_transparent(), field_entry::get_underwater_age_speedup(), MonsterGroupManager::GetResultFromGroup(), map_data_common_t::has_flag(), has_flag(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), i_at(), int_id< T >::id(), ter_t::id, string_id< T >::id(), impassable(), field_entry::intensity_upgrade_chance(), field_entry::intensity_upgrade_duration(), field_entry::is_field_alive(), itype_rock, m_bad, MAPSIZE, maptile_at_internal(), field_entry::mod_field_age(), field_entry::monster_spawn_chance(), field_entry::monster_spawn_count(), field_entry::monster_spawn_group(), field_entry::monster_spawn_radius(), MonsterGroupResult::name, field_type::npc_complain_data, int_id< T >::obj(), obstructed_by_vehicle_rotation(), calendar::once_every(), one_in(), field_type::outdoor_age_speedup, OVERMAP_DEPTH, OVERMAP_HEIGHT, MonsterGroupResult::pack_size, passable(), field_type::percent_spread, point_zero, points_in_radius(), maptile::pos_, random_entry(), random_entry_removed(), random_point(), field::remove_field(), rl_dist(), rng(), roll_remainder(), SEEX, SEEY, item::set_age(), field_entry::set_field_age(), field_entry::set_field_intensity(), set_seen_cache_dirty(), set_transparency_cache_dirty(), spawn_items(), fungal_effects::spread_fungus(), spread_gas(), squares_in_direction(), t_dirt, t_open_air, t_pit, ter(), ter_furn_has_flag(), ter_set(), TFLAG_ALLOW_FIELD_EFFECT, TFLAG_FIRE_CONTAINER, TFLAG_FLAMMABLE, TFLAG_FLAMMABLE_ASH, TFLAG_FLAMMABLE_HARD, TFLAG_NO_FLOOR, TFLAG_SEALED, TFLAG_SWIMMABLE, item::tname(), valid_move(), veh_at_internal(), field_type::wandering_field, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, tripoint::z, and zlevels.

Referenced by process_fields().

◆ process_items()

void map::process_items ( )

Definition at line 4700 of file map.cpp.

4701{
4702 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
4703 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
4704 for( int gz = minz; gz <= maxz; ++gz ) {
4705 level_cache &cache = access_cache( gz );
4706 std::set<tripoint> submaps_with_vehicles;
4707 for( vehicle *this_vehicle : cache.vehicle_list ) {
4708 tripoint pos = this_vehicle->global_pos3();
4709 submaps_with_vehicles.emplace( pos.x / SEEX, pos.y / SEEY, pos.z );
4710 }
4711 for( const tripoint &pos : submaps_with_vehicles ) {
4712 submap *const current_submap = get_submap_at_grid( pos );
4713 // Vehicles first in case they get blown up and drop active items on the map.
4714 process_items_in_vehicles( *current_submap );
4715 }
4716 }
4717 // Making a copy, in case the original variable gets modified during `process_items_in_submap`
4718 const std::set<tripoint> submaps_with_active_items_copy = submaps_with_active_items;
4719 for( const tripoint &abs_pos : submaps_with_active_items_copy ) {
4720 const tripoint local_pos = abs_pos - abs_sub.xy();
4721 submap *const current_submap = get_submap_at_grid( local_pos );
4722 if( !current_submap->active_items.empty() ) {
4723 process_items_in_submap( *current_submap, local_pos );
4724 }
4725 }
4726}
void process_items_in_vehicles(submap &current_submap)
Definition: map.cpp:4763
void process_items_in_submap(submap &current_submap, const tripoint &gridp)
Definition: map.cpp:4743

References abs_sub, access_cache(), submap::active_items, active_item_cache::empty(), get_submap_at_grid(), vehicle::global_pos3(), OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::pos, process_items_in_submap(), process_items_in_vehicles(), SEEX, SEEY, submaps_with_active_items, level_cache::vehicle_list, tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_items_in_submap()

void map::process_items_in_submap ( submap current_submap,
const tripoint gridp 
)
private

Definition at line 4743 of file map.cpp.

4744{
4745 // Get a COPY of the active item list for this submap.
4746 // If more are added as a side effect of processing, they are ignored this turn.
4747 // If they are destroyed before processing, they don't get processed.
4748 std::vector<item_reference> active_items = current_submap.active_items.get_for_processing();
4749 const point grid_offset( gridp.x * SEEX, gridp.y * SEEY );
4750 for( item_reference &active_item_ref : active_items ) {
4751 if( !active_item_ref.item_ref ) {
4752 // The item was destroyed, so skip it.
4753 continue;
4754 }
4755
4756 const tripoint map_location = tripoint( grid_offset + active_item_ref.location, gridp.z );
4757 temperature_flag flag = temperature_flag_at_point( *this, map_location );
4758 map_stack items = i_at( map_location );
4759 process_map_items( items, active_item_ref.item_ref, map_location, flag );
4760 }
4761}
std::vector< item_reference > get_for_processing()
Returns the first size() / processing_speed() elements of each list, rounded up.
static bool process_map_items(item_stack &items, safe_reference< item > &item_ref, const tripoint &location, const temperature_flag flag)
Definition: map.cpp:4586

References submap::active_items, active_item_cache::get_for_processing(), i_at(), process_map_items(), SEEX, SEEY, temperature_flag_at_point(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by process_items().

◆ process_items_in_vehicle()

void map::process_items_in_vehicle ( vehicle cur_veh,
submap current_submap 
)
private

Definition at line 4784 of file map.cpp.

4785{
4786 const bool engine_heater_is_on = cur_veh.has_part( "E_HEATER", true ) && cur_veh.engine_on;
4787 for( const vpart_reference &vp : cur_veh.get_any_parts( VPFLAG_FLUIDTANK ) ) {
4788 vp.part().process_contents( vp.pos(), engine_heater_is_on );
4789 }
4790
4791 auto cargo_parts = cur_veh.get_parts_including_carried( VPFLAG_CARGO );
4792 for( const vpart_reference &vp : cargo_parts ) {
4793 process_vehicle_items( cur_veh, vp.part_index() );
4794 }
4795
4796 for( item_reference &active_item_ref : cur_veh.active_items.get_for_processing() ) {
4797 if( empty( cargo_parts ) ) {
4798 return;
4799 } else if( !active_item_ref.item_ref ) {
4800 // The item was destroyed, so skip it.
4801 continue;
4802 }
4803 const auto it = std::find_if( begin( cargo_parts ),
4804 end( cargo_parts ), [&]( const vpart_reference & part ) {
4805 return active_item_ref.location == part.mount();
4806 } );
4807
4808 if( it == end( cargo_parts ) ) {
4809 continue; // Can't find a cargo part matching the active item.
4810 }
4811 const item &target = *active_item_ref.item_ref;
4812 // Find the cargo part and coordinates corresponding to the current active item.
4813 const vehicle_part &pt = it->part();
4814 const tripoint item_loc = it->pos();
4815 auto items = cur_veh.get_items( static_cast<int>( it->part_index() ) );
4817 if( target.is_food() || target.is_food_container() || target.is_corpse() ) {
4818 const vpart_info &pti = pt.info();
4819 if( engine_heater_is_on ) {
4821 }
4822
4823 if( pt.enabled && pti.has_flag( VPFLAG_FRIDGE ) ) {
4825 } else if( pt.enabled && pti.has_flag( VPFLAG_FREEZER ) ) {
4827 }
4828 }
4829 if( !process_map_items( items, active_item_ref.item_ref, item_loc, flag ) ) {
4830 // If the item was NOT destroyed, we can skip the remainder,
4831 // which handles fallout from the vehicle being damaged.
4832 continue;
4833 }
4834
4835 // item does not exist anymore, might have been an exploding bomb,
4836 // check if the vehicle is still valid (does exist)
4837 if( !current_submap.contains_vehicle( &cur_veh ) ) {
4838 // Nope, vehicle is not in the vehicle list of the submap,
4839 // it might have moved to another submap (unlikely)
4840 // or be destroyed, anyway it does not need to be processed here
4841 return;
4842 }
4843
4844 // Vehicle still valid, reload the list of cargo parts,
4845 // the list of cargo parts might have changed (imagine a part with
4846 // a low index has been removed by an explosion, all the other
4847 // parts would move up to fill the gap).
4848 cargo_parts = cur_veh.get_any_parts( VPFLAG_CARGO );
4849 }
4850}
bool is_food_container() const
Definition: item.cpp:6634
bool is_corpse() const
Whether this is a corpse item.
Definition: item.cpp:6646
bool contains_vehicle(vehicle *)
Definition: submap.cpp:256
bool engine_on
Definition: vehicle.h:1721
vehicle_part_with_feature_range< std::string > get_parts_including_carried(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are not broken or remove...
Definition: vehicle.cpp:2732
bool has_part(const std::string &flag, bool enabled=false) const
Check if vehicle has at least one unbroken part with specified flag.
Definition: vehicle.cpp:2562
active_item_cache active_items
Definition: vehicle.h:1596
vehicle_part_with_feature_range< std::string > get_any_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and not removed.
Definition: vehicle.cpp:2746
point mount() const
Returns the mount point: the point in the vehicles own coordinate system.
Definition: vehicle.cpp:6812
static void process_vehicle_items(vehicle &cur_veh, int part)
Definition: map.cpp:4601
const vpart_info & info() const
Get part definition common to all parts of this type.
@ VPFLAG_FLUIDTANK
Definition: veh_type.h:73
@ VPFLAG_FREEZER
Definition: veh_type.h:58
@ VPFLAG_FRIDGE
Definition: veh_type.h:57

References vehicle::active_items, submap::contains_vehicle(), vehicle_part::enabled, vehicle::engine_on, vehicle::get_any_parts(), active_item_cache::get_for_processing(), vehicle::get_items(), vehicle::get_parts_including_carried(), vpart_info::has_flag(), vehicle::has_part(), vehicle_part::info(), item::is_corpse(), item::is_food(), item::is_food_container(), vpart_position::mount(), process_map_items(), process_vehicle_items(), TEMP_FREEZER, TEMP_FRIDGE, TEMP_HEATER, TEMP_NORMAL, VPFLAG_CARGO, VPFLAG_FLUIDTANK, VPFLAG_FREEZER, and VPFLAG_FRIDGE.

Referenced by process_items_in_vehicles().

◆ process_items_in_vehicles()

void map::process_items_in_vehicles ( submap current_submap)
private

Definition at line 4763 of file map.cpp.

4764{
4765 // a copy, important if the vehicle list changes because a
4766 // vehicle got destroyed by a bomb (an active item!), this list
4767 // won't change, but veh_in_nonant will change.
4768 std::vector<vehicle *> vehicles;
4769 for( const auto &veh : current_submap.vehicles ) {
4770 vehicles.push_back( veh.get() );
4771 }
4772 for( auto &cur_veh : vehicles ) {
4773 if( !current_submap.contains_vehicle( cur_veh ) ) {
4774 // vehicle not in the vehicle list of the nonant, has been
4775 // destroyed (or moved to another nonant?)
4776 // Can't be sure that it still exists, so skip it
4777 continue;
4778 }
4779
4780 process_items_in_vehicle( *cur_veh, current_submap );
4781 }
4782}
void process_items_in_vehicle(vehicle &cur_veh, submap &current_submap)
Definition: map.cpp:4784

References submap::contains_vehicle(), process_items_in_vehicle(), and submap::vehicles.

Referenced by process_items().

◆ produce_sap()

void map::produce_sap ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Produce sap on tapped maple trees.

Parameters
pLocation of tapped tree
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7384 of file map.cpp.

7385{
7386 if( time_since_last_actualize <= 0_turns ) {
7387 return;
7388 }
7389
7390 if( t_tree_maple_tapped != ter( p ) ) {
7391 return;
7392 }
7393
7394 // Amount of maple sap liters produced per season per tap
7395 static const int maple_sap_per_season = 56;
7396
7397 // How many turns to produce 1 charge (250 ml) of sap?
7398 const time_duration producing_length = 0.75 * calendar::season_length();
7399
7400 const time_duration turns_to_produce = producing_length / ( maple_sap_per_season * 4 );
7401
7402 // How long of this time_since_last_actualize have we been in the producing period (late winter, early spring)?
7403 time_duration time_producing = 0_turns;
7404
7405 if( time_since_last_actualize >= calendar::year_length() ) {
7406 time_producing = producing_length;
7407 } else {
7408 // We are only producing sap on the intersection with the sap producing season.
7409 const time_duration early_spring_end = 0.5f * calendar::season_length();
7410 const time_duration late_winter_start = 3.75f * calendar::season_length();
7411
7412 const time_point last_actualize = calendar::turn - time_since_last_actualize;
7413 const time_duration last_actualize_tof = time_past_new_year( last_actualize );
7414 bool last_producing = (
7415 last_actualize_tof >= late_winter_start ||
7416 last_actualize_tof < early_spring_end
7417 );
7418 const time_duration current_tof = time_past_new_year( calendar::turn );
7419 bool current_producing = (
7420 current_tof >= late_winter_start ||
7421 current_tof < early_spring_end
7422 );
7423
7424 const time_duration non_producing_length = 3.25 * calendar::season_length();
7425
7426 if( last_producing && current_producing ) {
7427 if( time_since_last_actualize < non_producing_length ) {
7428 time_producing = time_since_last_actualize;
7429 } else {
7430 time_producing = time_since_last_actualize - non_producing_length;
7431 }
7432 } else if( !last_producing && !current_producing ) {
7433 if( time_since_last_actualize > non_producing_length ) {
7434 time_producing = time_since_last_actualize - non_producing_length;
7435 }
7436 } else if( last_producing && !current_producing ) {
7437 // We hit the end of early spring
7438 if( last_actualize_tof < early_spring_end ) {
7439 time_producing = early_spring_end - last_actualize_tof;
7440 } else {
7441 time_producing = calendar::year_length() - last_actualize_tof + early_spring_end;
7442 }
7443 } else if( !last_producing && current_producing ) {
7444 // We hit the start of late winter
7445 if( current_tof >= late_winter_start ) {
7446 time_producing = current_tof - late_winter_start;
7447 } else {
7448 time_producing = 0.25f * calendar::season_length() + current_tof;
7449 }
7450 }
7451 }
7452
7453 int new_charges = roll_remainder( time_producing / turns_to_produce );
7454 // Not enough time to produce 1 charge of sap
7455 if( new_charges <= 0 ) {
7456 return;
7457 }
7458
7459 item sap( "maple_sap", calendar::turn );
7460
7461 // Is there a proper container?
7462 auto items = i_at( p );
7463 for( auto &it : items ) {
7464 if( it.is_bucket() || it.is_watertight_container() ) {
7465 const int capacity = it.get_remaining_capacity_for_liquid( sap, true );
7466 if( capacity > 0 ) {
7467 new_charges = std::min( new_charges, capacity );
7468
7469 // The environment might have poisoned the sap with animals passing by, insects, leaves or contaminants in the ground
7470 sap.poison = one_in( 10 ) ? 1 : 0;
7471 sap.charges = new_charges;
7472
7473 it.fill_with( sap );
7474 }
7475 // Only fill up the first container.
7476 break;
7477 }
7478 }
7479}
time_duration time_past_new_year(const time_point &p)
Definition: calendar.h:502
A point in the game time.
Definition: calendar.h:431
ter_id t_tree_maple_tapped
Definition: mapdata.cpp:684
time_duration year_length()
Definition: calendar.cpp:461
time_duration season_length()
Definition: calendar.cpp:466

References item::charges, i_at(), one_in(), item::poison, roll_remainder(), calendar::season_length(), t_tree_maple_tapped, ter(), time_past_new_year(), calendar::turn, and calendar::year_length().

Referenced by actualize().

◆ propagate_field()

void map::propagate_field ( const tripoint center,
const field_type_id type,
int  amount,
int  max_intensity = 0 
)

Definition at line 1941 of file map_field.cpp.

1943{
1944 using gas_blast = std::pair<float, tripoint>;
1945 std::priority_queue<gas_blast, std::vector<gas_blast>, pair_greater_cmp_first> open;
1946 std::set<tripoint> closed;
1947 open.push( { 0.0f, center } );
1948
1949 const bool not_gas = type.obj().phase != GAS;
1950
1951 while( amount > 0 && !open.empty() ) {
1952 if( closed.count( open.top().second ) ) {
1953 open.pop();
1954 continue;
1955 }
1956
1957 // All points with equal gas intensity should propagate at the same time
1958 std::list<gas_blast> gas_front;
1959 gas_front.push_back( open.top() );
1960 const int cur_intensity = get_field_intensity( open.top().second, type );
1961 open.pop();
1962 while( !open.empty() && get_field_intensity( open.top().second, type ) == cur_intensity ) {
1963 if( closed.count( open.top().second ) == 0 ) {
1964 gas_front.push_back( open.top() );
1965 }
1966
1967 open.pop();
1968 }
1969
1970 int increment = std::max<int>( 1, amount / gas_front.size() );
1971
1972 while( !gas_front.empty() ) {
1973 gas_blast gp = random_entry_removed( gas_front );
1974 closed.insert( gp.second );
1975 const int cur_intensity = get_field_intensity( gp.second, type );
1976 if( cur_intensity < max_intensity ) {
1977 const int bonus = std::min( max_intensity - cur_intensity, increment );
1978 mod_field_intensity( gp.second, type, bonus );
1979 amount -= bonus;
1980 } else {
1981 amount--;
1982 }
1983
1984 if( amount <= 0 ) {
1985 return;
1986 }
1987
1988 static const std::array<int, 8> x_offset = {{ -1, 1, 0, 0, 1, -1, -1, 1 }};
1989 static const std::array<int, 8> y_offset = {{ 0, 0, -1, 1, -1, 1, -1, 1 }};
1990 for( size_t i = 0; i < 8; i++ ) {
1991 tripoint pt = gp.second + point( x_offset[ i ], y_offset[ i ] );
1992 if( closed.count( pt ) > 0 ) {
1993 continue;
1994 }
1995
1996 if( impassable( pt ) && ( not_gas || !has_flag( TFLAG_PERMEABLE, pt ) ) ) {
1997 closed.insert( pt );
1998 continue;
1999 }
2000 if( !obstructed_by_vehicle_rotation( gp.second, pt ) ) {
2001 open.push( { static_cast<float>( rl_dist( center, pt ) ), pt } );
2002 }
2003 }
2004 }
2005 }
2006}
@ GAS
Definition: enums.h:175
Greater-than comparison operator; required by the sort interface.
Definition: cata_utility.h:20

References center, GAS, get_field_intensity(), has_flag(), impassable(), mod_field_intensity(), obstructed_by_vehicle_rotation(), open(), random_entry_removed(), rl_dist(), TFLAG_PERMEABLE, and type.

Referenced by emit_field().

◆ propagate_suspension_check()

void map::propagate_suspension_check ( const tripoint point)

Checks surrounding tiles for suspension, and has them check for collapse.

!!Should only be called after the tile at this point has been destroyed!!

Definition at line 3006 of file map.cpp.

3007{
3008 for( const tripoint &neighbor : points_in_radius( point, 1 ) ) {
3009 if( neighbor != point && has_flag( TFLAG_SUSPENDED, neighbor ) ) {
3010 collapse_invalid_suspension( neighbor );
3011 }
3012 }
3013}

References collapse_invalid_suspension(), has_flag(), points_in_radius(), and TFLAG_SUSPENDED.

Referenced by bash_ter_success(), collapse_at(), and collapse_invalid_suspension().

◆ put_items_from_loc()

std::vector< item * > map::put_items_from_loc ( const item_group_id loc,
const tripoint p,
const time_point turn = calendar::start_of_cataclysm 
)

Place items from an item group at p.

Places as much items as the item group says. (Most item groups are distributions and will only create one item.)

Parameters
locCurrent location of items
pDestination of items
turnThe birthday that the created items shall have.
Returns
Vector of pointers to placed items (can be empty, but no nulls).

Definition at line 5409 of file mapgen.cpp.

5411{
5412 const auto items = item_group::items_from( loc, turn );
5413 return spawn_items( p, items );
5414}

References item_group::items_from(), spawn_items(), and calendar::turn.

Referenced by add_corpse(), mapgen_cavern(), MapExtras::mx_corpses(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), and place_items().

◆ rad_scorch()

void map::rad_scorch ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Radiation-related plant (and fungus?) death.

Definition at line 7481 of file map.cpp.

7482{
7483 const int rads = get_radiation( p );
7484 if( rads == 0 ) {
7485 return;
7486 }
7487
7488 // TODO: More interesting rad scorch chance - base on season length?
7489 if( !x_in_y( 1.0 * rads * rads * time_since_last_actualize, 91_days ) ) {
7490 return;
7491 }
7492
7493 // First destroy the farmable plants (those are furniture)
7494 // TODO: Rad-resistant mutant plants (that produce radioactive fruit)
7495 const furn_t &fid = furn( p ).obj();
7496 if( fid.has_flag( "PLANT" ) ) {
7497 i_clear( p );
7498 furn_set( p, f_null );
7499 }
7500
7501 const ter_id tid = ter( p );
7502 // TODO: De-hardcode this
7503 static const std::map<ter_id, ter_str_id> dies_into {{
7504 {t_grass, ter_str_id( "t_dirt" )},
7505 {t_tree_young, ter_str_id( "t_dirt" )},
7506 {t_tree_pine, ter_str_id( "t_tree_deadpine" )},
7507 {t_tree_birch, ter_str_id( "t_tree_birch_harvested" )},
7508 {t_tree_willow, ter_str_id( "t_tree_willow_harvested" )},
7509 {t_tree_hickory, ter_str_id( "t_tree_hickory_dead" )},
7510 {t_tree_hickory_harvested, ter_str_id( "t_tree_hickory_dead" )},
7511 }};
7512
7513 const auto iter = dies_into.find( tid );
7514 if( iter != dies_into.end() ) {
7515 ter_set( p, iter->second );
7516 return;
7517 }
7518
7519 const ter_t &tr = tid.obj();
7520 if( tr.has_flag( "SHRUB" ) ) {
7521 ter_set( p, t_dirt );
7522 } else if( tr.has_flag( "TREE" ) ) {
7523 ter_set( p, ter_str_id( "t_tree_dead" ) );
7524 }
7525}
int get_radiation(const tripoint &p) const
Definition: map.cpp:4154
ter_id t_tree_hickory_harvested
Definition: mapdata.cpp:685
ter_id t_tree_willow
Definition: mapdata.cpp:684
ter_id t_tree_birch
Definition: mapdata.cpp:684
ter_id t_tree_pine
Definition: mapdata.cpp:684
ter_id t_tree_young
Definition: mapdata.cpp:680
ter_id t_tree_hickory
Definition: mapdata.cpp:685
string_id< ter_t > ter_str_id
Definition: mapdata.h:25

References f_null, furn(), furn_set(), get_radiation(), map_data_common_t::has_flag(), i_clear(), int_id< T >::obj(), t_dirt, t_grass, t_tree_birch, t_tree_hickory, t_tree_hickory_harvested, t_tree_pine, t_tree_willow, t_tree_young, ter(), ter_set(), and x_in_y().

Referenced by actualize().

◆ random_outdoor_tile()

point map::random_outdoor_tile ( )

Definition at line 2793 of file map.cpp.

2794{
2795 std::vector<point> options;
2796 for( const tripoint &p : points_on_zlevel() ) {
2797 if( is_outside( p.xy() ) ) {
2798 options.push_back( p.xy() );
2799 }
2800 }
2802}
std::string options()
Definition: path_info.cpp:230

References is_outside(), PATH_INFO::options(), point_north_west, points_on_zlevel(), and random_entry().

◆ ranged_target_size()

double map::ranged_target_size ( const tripoint p) const

Size of map objects at p for purposes of ranged combat.

Size is in percentage of tile: if 1.0, all attacks going through tile should hit map objects on it, if 0.0 there is nothing to be hit (air/water).

Definition at line 2020 of file map.cpp.

2021{
2022 if( impassable( p ) ) {
2023 return 1.0;
2024 }
2025
2026 if( !has_floor( p ) ) {
2027 return 0.0;
2028 }
2029
2030 // TODO: Handle cases like shrubs, trees, furniture, sandbags...
2031 return 0.1;
2032}

References has_floor(), and impassable().

◆ reachable_flood_steps()

void map::reachable_flood_steps ( std::vector< tripoint > &  reachable_pts,
const tripoint f,
int  range,
int  cost_min,
int  cost_max 
) const

Populates a vector of points that are reachable within a number of steps from a point.

It could be generalized to take advantage of z levels, but would need some additional code to detect whether a valid transition was on a tile.

Does the following:

  1. Checks if a point is reachable using a flood fill and if it is, adds it to a vector.

Definition at line 6425 of file map.cpp.

6427{
6428 struct pq_item {
6429 int dist;
6430 int ndx;
6431 };
6432 struct pq_item_comp {
6433 bool operator()( const pq_item &left, const pq_item &right ) {
6434 return left.dist > right.dist;
6435 }
6436 };
6437 using PQ_type = std::priority_queue< pq_item, std::vector<pq_item>, pq_item_comp>;
6438
6439 // temp buffer for grid
6440 const int grid_dim = range * 2 + 1;
6441 // init to -1 as "not visited yet"
6442 std::vector< int > t_grid( static_cast<size_t>( grid_dim * grid_dim ), -1 );
6443 const tripoint origin_offset = {range, range, 0};
6444 const int initial_visit_distance = range * range; // Large unreachable value
6445
6446 // Fill positions that are visitable with initial_visit_distance
6447 for( const tripoint &p : points_in_radius( f, range ) ) {
6448 const tripoint tp = { p.xy(), f.z };
6449 const int tp_cost = move_cost( tp );
6450 // rejection conditions
6451 if( tp_cost < cost_min || tp_cost > cost_max || !has_floor_or_support( tp ) ) {
6452 continue;
6453 }
6454 // set initial cost for grid point
6455 tripoint origin_relative = tp - f;
6456 origin_relative += origin_offset;
6457 int ndx = origin_relative.x + origin_relative.y * grid_dim;
6458 t_grid[ ndx ] = initial_visit_distance;
6459 }
6460
6461 auto gen_neighbors = []( const pq_item & elem, int grid_dim, pq_item * neighbors ) {
6462 // Up to 8 neighbors
6463 int new_cost = elem.dist + 1;
6464 // *INDENT-OFF*
6465 int ox[8] = {
6466 -1, 0, 1,
6467 -1, 1,
6468 -1, 0, 1
6469 };
6470 int oy[8] = {
6471 -1, -1, -1,
6472 0, 0,
6473 1, 1, 1
6474 };
6475 // *INDENT-ON*
6476
6477 point e( elem.ndx % grid_dim, elem.ndx / grid_dim );
6478 for( int i = 0; i < 8; ++i ) {
6479 point n( e + point( ox[i], oy[i] ) );
6480
6481 int ndx = n.x + n.y * grid_dim;
6482 neighbors[i] = { new_cost, ndx };
6483 }
6484 };
6485
6486 PQ_type pq( pq_item_comp{} );
6487 pq_item first_item{ 0, range + range * grid_dim };
6488 pq.push( first_item );
6489 pq_item neighbor_elems[8];
6490
6491 while( !pq.empty() ) {
6492 const pq_item item = pq.top();
6493 pq.pop();
6494
6495 if( t_grid[ item.ndx ] == initial_visit_distance ) {
6496 t_grid[ item.ndx ] = item.dist;
6497 if( item.dist + 1 < range ) {
6498 gen_neighbors( item, grid_dim, neighbor_elems );
6499 for( pq_item neighbor_elem : neighbor_elems ) {
6500 pq.push( neighbor_elem );
6501 }
6502 }
6503 }
6504 }
6505 std::vector<char> o_grid( static_cast<size_t>( grid_dim * grid_dim ), 0 );
6506 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6507 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6508 if( t_grid[ ndx ] != -1 && t_grid[ ndx ] < initial_visit_distance ) {
6509 // set self and neighbors to 1
6510 for( int dy = -1; dy <= 1; ++dy ) {
6511 for( int dx = -1; dx <= 1; ++dx ) {
6512 int tx = dx + x;
6513 int ty = dy + y;
6514
6515 if( tx >= 0 && tx < grid_dim && ty >= 0 && ty < grid_dim ) {
6516 o_grid[ tx + ty * grid_dim ] = 1;
6517 }
6518 }
6519 }
6520 }
6521 }
6522 }
6523
6524 // Now go over again to pull out all of the reachable points
6525 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6526 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6527 if( o_grid[ ndx ] ) {
6528 tripoint t = f - origin_offset + tripoint{ x, y, 0 };
6529 reachable_pts.push_back( t );
6530 }
6531 }
6532 }
6533}

References has_floor_or_support(), left, move_cost(), points_in_radius(), range, right, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by inventory::form_from_map(), and use_charges().

◆ register_vehicle_zone()

void map::register_vehicle_zone ( vehicle veh,
int  zlev 
)

Definition at line 1017 of file map.cpp.

1018{
1019 auto &ch = get_cache( zlev );
1020 ch.zone_vehicles.insert( veh );
1021}

References get_cache().

Referenced by zone_manager::create_vehicle_loot_zone().

◆ remove_field()

void map::remove_field ( const tripoint p,
const field_type_id field_to_remove 
)

Remove field entry at xy, ignored if the field entry is not present.

Definition at line 5593 of file map.cpp.

5594{
5595 if( !inbounds( p ) ) {
5596 return;
5597 }
5598
5599 point l;
5600 submap *const current_submap = get_submap_at( p, l );
5601
5602 if( current_submap->get_field( l ).remove_field( field_to_remove ) ) {
5603 // Only adjust the count if the field actually existed.
5604 if( !--current_submap->field_count ) {
5605 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5606 p.y / SEEX ) * MAPSIZE ) ) );
5607 }
5608 const auto &fdata = field_to_remove.obj();
5609 if( fdata.dirty_transparency_cache || !fdata.is_transparent() ) {
5612 }
5613 if( fdata.is_dangerous() ) {
5615 }
5616 }
5617}

References level_cache::field_cache, submap::field_count, get_cache(), submap::get_field(), get_submap_at(), inbounds(), MAPSIZE, int_id< T >::obj(), field::remove_field(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by bash_field(), game::grabbed_furn_move(), MapExtras::mx_house_spider(), MapExtras::mx_spider(), game::process_artifact(), set_field_intensity(), shoot(), and game::walk_move().

◆ remove_rotten_items()

template<typename Container >
void map::remove_rotten_items ( Container &  items,
const tripoint p,
temperature_flag  temperature 
)
protected

Go through the list of items, update their rotten status and remove items that have rotten away completely.

Parameters
itemsitems to remove
pThe point on this map where the items are, used for rot calculation.
temperatureflag that overrides temperature processing at certain locations

Definition at line 7230 of file map.cpp.

7231{
7232 for( auto it = items.begin(); it != items.end(); ) {
7233 if( it->actualize_rot( pnt, temperature, get_weather() ) ) {
7234 if( it->is_comestible() ) {
7235 rotten_item_spawn( *it, pnt );
7236 }
7237 it = i_rem( pnt, it );
7238 } else {
7239 ++it;
7240 }
7241 }
7242}

References get_weather(), i_rem(), and rotten_item_spawn().

Referenced by actualize().

◆ remove_submap_camp()

void map::remove_submap_camp ( const tripoint p)

Definition at line 5708 of file map.cpp.

5709{
5710 get_submap_at( p )->camp.reset();
5711}

References submap::camp, and get_submap_at().

Referenced by game::validate_camps().

◆ remove_trap()

void map::remove_trap ( const tripoint p)

Definition at line 5394 of file map.cpp.

5395{
5396 if( !inbounds( p ) ) {
5397 return;
5398 }
5399
5400 point l;
5401 submap *const current_submap = get_submap_at( p, l );
5402
5403 trap_id tid = current_submap->get_trap( l );
5404 if( tid != tr_null ) {
5405 if( g != nullptr && this == &get_map() ) {
5406 g->u.add_known_trap( p, tr_null.obj() );
5407 }
5408
5409 current_submap->set_trap( l, tr_null );
5410 auto &traps = traplocs[tid.to_i()];
5411 const auto iter = std::find( traps.begin(), traps.end(), p );
5412 if( iter != traps.end() ) {
5413 traps.erase( iter );
5414 }
5415 }
5416}
void set_trap(point p, trap_id trap)
Definition: submap.h:77

References detail::find(), g, get_map(), get_submap_at(), submap::get_trap(), inbounds(), int_id< T >::obj(), submap::set_trap(), int_id< T >::to_i(), tr_null, and traplocs.

Referenced by mremove_trap(), trap::on_disarmed(), game::process_artifact(), and trap_set().

◆ reset_vehicle_cache()

void map::reset_vehicle_cache ( )

Definition at line 314 of file map.cpp.

315{
318
319 // Cache all vehicles
320 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
321 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
322 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
323 auto &ch = get_cache( zlev );
324 for( const auto &elem : ch.vehicle_list ) {
325 elem->adjust_zlevel( 0, tripoint_zero );
326 add_vehicle_to_cache( elem );
327 }
328 }
329}
void clear_vehicle_cache()
Definition: map.cpp:373

References abs_sub, add_vehicle_to_cache(), clear_vehicle_cache(), get_cache(), last_full_vehicle_list_dirty, OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint_zero, tripoint::z, and zlevels.

Referenced by detach_vehicle(), editmap::draw_main_ui_overlay(), load(), loadn(), rotate(), shift(), and vehicle::use_bike_rack().

◆ restock_fruits()

void map::restock_fruits ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Try to grow fruits on static plants (not planted by the player)

Parameters
pPlace to restock
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7370 of file map.cpp.

7371{
7372 const auto &ter = this->ter( p ).obj();
7373 if( !ter.has_flag( TFLAG_HARVESTED ) ) {
7374 return; // Already harvestable. Do nothing.
7375 }
7376 // Make it harvestable again if the last actualization was during a different season or year.
7377 const time_point last_touched = calendar::turn - time_since_last_actualize;
7378 if( season_of_year( calendar::turn ) != season_of_year( last_touched ) ||
7379 time_since_last_actualize >= calendar::season_length() ) {
7380 ter_set( p, ter.transforms_into );
7381 }
7382}
season_type season_of_year(const time_point &p)
Definition: calendar.cpp:547

References int_id< T >::obj(), calendar::season_length(), season_of_year(), ter(), ter_set(), TFLAG_HARVESTED, and calendar::turn.

Referenced by actualize(), and saven().

◆ restore_vision_transparency_cache()

void map::restore_vision_transparency_cache ( const tripoint center,
int  target_z,
float(&)  vision_restore_cache[9],
bool(&)  blocked_restore_cache[8] 
)
protected

Definition at line 1506 of file lightmap.cpp.

1508{
1509 auto &map_cache = get_cache( target_z );
1510 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.transparency_cache;
1511 diagonal_blocks( &blocked_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vehicle_obscured_cache;
1512
1513 int i = 0;
1514 for( point adjacent : eight_adjacent_offsets ) {
1515 const tripoint p = center + adjacent;
1516 if( !inbounds( p ) ) {
1517 continue;
1518 }
1519 transparency_cache[p.x][p.y] = vision_restore_cache[i];
1520
1521 if( blocked_restore_cache[i] ) {
1522 bool &relevant_blocked = adjacent == point_north_east ? blocked_cache[center.x][center.y].ne :
1523 adjacent == point_south_east ? blocked_cache[p.x][p.y].nw :
1524 adjacent == point_south_west ? blocked_cache[p.x][p.y].ne :
1525 /* point_north_west */ blocked_cache[center.x][center.y].nw;
1526 relevant_blocked = false;
1527 }
1528
1529 i++;
1530 }
1531 transparency_cache[center.x][center.y] = vision_restore_cache[8];
1532}

References center, eight_adjacent_offsets, get_cache(), inbounds(), MAPSIZE_X, MAPSIZE_Y, point_north_east, point_south_east, point_south_west, tripoint::x, and tripoint::y.

Referenced by build_seen_cache().

◆ rotate()

void map::rotate ( int  turns,
bool  setpos_safe = false 
)

Rotates this map, and all of its contents, by the specified multiple of 90 degrees.

Parameters
turnsHow many 90-degree turns to rotate the map.

Definition at line 5636 of file mapgen.cpp.

5637{
5638
5639 //Handle anything outside the 1-3 range gracefully; rotate(0) is a no-op.
5640 turns = turns % 4;
5641 if( turns == 0 ) {
5642 return;
5643 }
5644
5645 real_coords rc;
5646 const tripoint &abs_sub = get_abs_sub();
5647 rc.fromabs( point( abs_sub.x * SEEX, abs_sub.y * SEEY ) );
5648
5649 // TODO: This radius can be smaller - how small?
5650 const int radius = HALF_MAPSIZE + 3;
5651 // uses submap coordinates
5652 // TODO: fix point types
5653 const std::vector<shared_ptr_fast<npc>> npcs =
5655 for( const shared_ptr_fast<npc> &i : npcs ) {
5656 npc &np = *i;
5657 const tripoint sq = np.global_square_location();
5658 const point local_sq = getlocal( sq ).xy();
5659
5660 real_coords np_rc;
5661 np_rc.fromabs( sq.xy() );
5662 // Note: We are rotating the entire overmap square (2x2 of submaps)
5663 if( np_rc.om_pos != rc.om_pos || sq.z != abs_sub.z ) {
5664 continue;
5665 }
5666
5667 // OK, this is ugly: we remove the NPC from the whole map
5668 // Then we place it back from scratch
5669 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5670
5671 point old( np_rc.sub_pos );
5672 if( np_rc.om_sub.x % 2 != 0 ) {
5673 old.x += SEEX;
5674 }
5675 if( np_rc.om_sub.y % 2 != 0 ) {
5676 old.y += SEEY;
5677 }
5678
5679 const point new_pos = old .rotate( turns, { SEEX * 2, SEEY * 2 } );
5680 if( setpos_safe ) {
5681 // setpos can't be used during mapgen, but spawn_at_precise clips position
5682 // to be between 0-11,0-11 and teleports NPCs when used inside of update_mapgen
5683 // calls
5684 const tripoint new_global_sq = sq - local_sq + new_pos;
5685 np.setpos( get_map().getlocal( new_global_sq ) );
5686 } else {
5687 // OK, this is ugly: we remove the NPC from the whole map
5688 // Then we place it back from scratch
5689 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5691 np.spawn_at_precise( { abs_sub.xy() }, { new_pos, abs_sub.z } );
5693 }
5694 }
5695
5698
5699 // Move the submaps around.
5700 if( turns == 2 ) {
5703 } else {
5704 point p;
5705 submap tmp;
5706
5708
5709 for( int k = 0; k < 4; ++k ) {
5710 p = p.rotate( turns, { 2, 2 } );
5712 }
5713 }
5714
5715 // Then rotate them and recalculate vehicle positions.
5716 for( int j = 0; j < 2; ++j ) {
5717 for( int i = 0; i < 2; ++i ) {
5718 point p( i, j );
5719 auto sm = get_submap_at_grid( p );
5720
5721 sm->rotate( turns );
5722
5723 for( auto &veh : sm->vehicles ) {
5724 veh->sm_pos = tripoint( p, abs_sub.z );
5725 }
5726
5728 }
5729 }
5731
5732 // rotate zones
5734 mgr.rotate_zones( *this, turns );
5735}
shared_ptr_fast< npc > npc_ptr
Definition: basecamp.h:46
character_id getID() const
Definition: character.cpp:495
void clear_vehicle_list(int zlev)
Definition: map.cpp:391
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:694
void spawn_at_precise(point submap_offset, const tripoint &square)
As spawn_at, but also sets position within the submap.
Definition: npc.cpp:742
tripoint global_square_location() const override
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: npc.cpp:752
std::vector< shared_ptr_fast< npc > > get_npcs_near(const tripoint_abs_sm &p, int radius)
Get all npcs in a area with given radius around given central point.
shared_ptr_fast< npc > remove_npc(const character_id &id)
Find npc by id and if found, erase it from the npc list and return it ( or return nullptr if not foun...
void rotate_zones(map &target_map, int turns)
Definition: clzones.cpp:1053
coords::coord_point< tripoint, coords::origin::abs, coords::sm > tripoint_abs_sm
Definition: coordinates.h:490
static constexpr int HALF_MAPSIZE
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496
point rotate(int turns, point dim={ 1, 1 }) const
Rotate point clockwise.
Definition: point.cpp:10
point om_sub
Definition: coordinates.h:638
void fromabs(point abs)
Definition: coordinates.cpp:3
point om_pos
Definition: coordinates.h:637
point sub_pos
Definition: coordinates.h:635

References abs_sub, clear_vehicle_cache(), clear_vehicle_list(), real_coords::fromabs(), get_abs_sub(), zone_manager::get_manager(), get_map(), overmapbuffer::get_npcs_near(), get_submap_at_grid(), Character::getID(), getlocal(), npc::global_square_location(), HALF_MAPSIZE, overmapbuffer::insert_npc(), real_coords::om_pos, real_coords::om_sub, overmap_buffer, point_east, point_south, point_south_east, point_zero, overmapbuffer::remove_npc(), reset_vehicle_cache(), point::rotate(), zone_manager::rotate_zones(), SEEX, SEEY, npc::setpos(), coords::sm, npc::spawn_at_precise(), real_coords::sub_pos, cata::swap(), update_vehicle_list(), point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by draw_connections(), draw_lab(), draw_office_tower(), draw_triffid(), mapgen_function_json::generate(), mapgen_ants_curved(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_forest_trail_curved(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_parking_lot(), editmap::mapgen_preview(), mapgen_railroad(), mapgen_railroad_bridge(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rotate(), mapgen_sewer_curved(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_subway(), and update_mapgen_function_json::update_map().

◆ rotten_item_spawn()

void map::rotten_item_spawn ( const item item,
const tripoint p 
)

Checks to see if the item that is rotting away generates a creature when it does.

Parameters
itemitem that is spawning creatures
pThe point on this map where the item is and creature will be

Definition at line 7244 of file map.cpp.

7245{
7246 if( g->critter_at( pnt ) != nullptr ) {
7247 return;
7248 }
7249 const auto &comest = item.get_comestible();
7250 mongroup_id mgroup = comest->rot_spawn;
7251 if( !mgroup ) {
7252 return;
7253 }
7254 const int chance = static_cast<int>( comest->rot_spawn_chance *
7255 get_option<float>( "CARRION_SPAWNRATE" ) );
7256 if( rng( 0, 100 ) < chance ) {
7258 add_spawn( spawn_details.name, 1, pnt, false );
7259 if( g->u.sees( pnt ) ) {
7260 if( item.is_seed() ) {
7261 add_msg( m_warning, _( "Something has crawled out of the %s plants!" ), item.get_plant_name() );
7262 } else {
7263 add_msg( m_warning, _( "Something has crawled out of the %s!" ), item.tname() );
7264 }
7265 }
7266 }
7267}
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:10154
std::string get_plant_name() const
The name of the plant as it appears in the various informational menus.
Definition: item.cpp:9823
bool is_seed() const
Whether this is actually a seed, the seed functions won't be of much use for non-seeds.
Definition: item.cpp:9804

References _, add_msg(), add_spawn(), g, item::get_comestible(), item::get_plant_name(), MonsterGroupManager::GetResultFromGroup(), item::is_seed(), m_warning, MonsterGroupResult::name, rng(), and item::tname().

Referenced by grow_plant(), and remove_rotten_items().

◆ route()

std::vector< tripoint > map::route ( const tripoint f,
const tripoint t,
const pathfinding_settings settings,
const std::set< tripoint > &  pre_closed = {{ }} 
) const

Calculate the best path using A*.

Parameters
fThe source location from which to path.
tThe destination to which to path.
settingsStructure describing pathfinding parameters.
pre_closedNever path through those points. They can still be the source or the destination.

Definition at line 195 of file pathfinding.cpp.

198{
199 /* TODO: If the origin or destination is out of bound, figure out the closest
200 * in-bounds point and go to that, then to the real origin/destination.
201 */
202 std::vector<tripoint> ret;
203
204 if( f == t || !inbounds( f ) ) {
205 return ret;
206 }
207
208 if( !inbounds( t ) ) {
209 tripoint clipped = t;
210 clip_to_bounds( clipped );
211 return route( f, clipped, settings, pre_closed );
212 }
213 // First, check for a simple straight line on flat ground
214 // Except when the line contains a pre-closed tile - we need to do regular pathing then
215 static const auto non_normal = PF_SLOW | PF_WALL | PF_VEHICLE | PF_TRAP | PF_SHARP;
216 if( f.z == t.z ) {
217 const auto line_path = line_to( f, t );
218 const auto &pf_cache = get_pathfinding_cache_ref( f.z );
219 // Check all points for any special case (including just hard terrain)
220 if( !( pf_cache.special[f.x][f.y] & non_normal ) &&
221 std::all_of( line_path.begin(), line_path.end(), [&pf_cache]( const tripoint & p ) {
222 return !( pf_cache.special[p.x][p.y] & non_normal );
223 } ) ) {
224 const std::set<tripoint> sorted_line( line_path.begin(), line_path.end() );
225
226 if( is_disjoint( sorted_line, pre_closed ) ) {
227 return line_path;
228 }
229 }
230 }
231
232 // If expected path length is greater than max distance, allow only line path, like above
233 if( rl_dist( f, t ) > settings.max_dist ) {
234 return ret;
235 }
236
237 int max_length = settings.max_length;
238 int bash = settings.bash_strength;
239 int climb_cost = settings.climb_cost;
240 bool doors = settings.allow_open_doors;
241 bool trapavoid = settings.avoid_traps;
242 bool roughavoid = settings.avoid_rough_terrain;
243 bool sharpavoid = settings.avoid_sharp;
244
245 const int pad = 16; // Should be much bigger - low value makes pathfinders dumb!
246 int minx = std::min( f.x, t.x ) - pad;
247 int miny = std::min( f.y, t.y ) - pad;
248 // TODO: Make this way bigger
249 int minz = std::min( f.z, t.z );
250 int maxx = std::max( f.x, t.x ) + pad;
251 int maxy = std::max( f.y, t.y ) + pad;
252 // Same TODO: as above
253 int maxz = std::max( f.z, t.z );
254 clip_to_bounds( minx, miny, minz );
255 clip_to_bounds( maxx, maxy, maxz );
256
257 pathfinder pf( point( minx, miny ), point( maxx, maxy ) );
258 // Make NPCs not want to path through player
259 // But don't make player pathing stop working
260 for( const auto &p : pre_closed ) {
261 if( p.x >= minx && p.x < maxx && p.y >= miny && p.y < maxy ) {
262 pf.close_point( p );
263 }
264 }
265
266 // Start and end must not be closed
267 pf.unclose_point( f );
268 pf.unclose_point( t );
269 pf.add_point( 0, 0, f, f );
270
271 bool done = false;
272
273 do {
274 auto cur = pf.get_next();
275
276 const int parent_index = flat_index( cur );
277 auto &layer = pf.get_layer( cur.z );
278 auto &cur_state = layer.state[parent_index];
279 if( cur_state == ASL_CLOSED ) {
280 continue;
281 }
282
283 if( layer.gscore[parent_index] > max_length ) {
284 // Shortest path would be too long, return empty vector
285 return std::vector<tripoint>();
286 }
287
288 if( cur == t ) {
289 done = true;
290 break;
291 }
292
293 cur_state = ASL_CLOSED;
294
295 const auto &pf_cache = get_pathfinding_cache_ref( cur.z );
296 const auto cur_special = pf_cache.special[cur.x][cur.y];
297
298 int cur_part;
299 const vehicle *cur_veh = veh_at_internal( cur, cur_part );
300
301 // 7 3 5
302 // 1 . 2
303 // 6 4 8
304 constexpr std::array<int, 8> x_offset{{ -1, 1, 0, 0, 1, -1, -1, 1 }};
305 constexpr std::array<int, 8> y_offset{{ 0, 0, -1, 1, -1, 1, -1, 1 }};
306 for( size_t i = 0; i < 8; i++ ) {
307 const tripoint p( cur.x + x_offset[i], cur.y + y_offset[i], cur.z );
308 const int index = flat_index( p );
309
310 // TODO: Remove this and instead have sentinels at the edges
311 if( p.x < minx || p.x >= maxx || p.y < miny || p.y >= maxy ) {
312 continue;
313 }
314
315 if( layer.state[index] == ASL_CLOSED ) {
316 continue;
317 }
318
319 int part = -1;
320 const vehicle *veh = veh_at_internal( p, part );
321 if( cur_veh &&
322 !cur_veh->allowed_move( cur_veh->tripoint_to_mount( cur ), cur_veh->tripoint_to_mount( p ) ) ) {
323 //Trying to squeeze through a vehicle hole, skip this movement but don't close the tile as other paths may lead to it
324 continue;
325 }
326
327 if( veh && veh != cur_veh &&
328 !veh->allowed_move( veh->tripoint_to_mount( cur ), veh->tripoint_to_mount( p ) ) ) {
329 //Same as above but moving into rather than out of a vehicle
330 continue;
331 }
332
333 // Penalize for diagonals or the path will look "unnatural"
334 int newg = layer.gscore[parent_index] + ( ( cur.x != p.x && cur.y != p.y ) ? 1 : 0 );
335
336 const auto p_special = pf_cache.special[p.x][p.y];
337 // TODO: De-uglify, de-huge-n
338 if( !( p_special & non_normal ) ) {
339 // Boring flat dirt - the most common case above the ground
340 newg += 2;
341 } else {
342 if( roughavoid ) {
343 layer.state[index] = ASL_CLOSED; // Close all rough terrain tiles
344 continue;
345 }
346
347 const maptile &tile = maptile_at_internal( p );
348 const auto &terrain = tile.get_ter_t();
349 const auto &furniture = tile.get_furn_t();
350
351 const int cost = move_cost_internal( furniture, terrain, veh, part );
352 // Don't calculate bash rating unless we intend to actually use it
353 const int rating = ( bash == 0 || cost != 0 ) ? -1 :
354 bash_rating_internal( bash, furniture, terrain, false, veh, part );
355
356 if( cost == 0 && rating <= 0 && ( !doors || !terrain.open || !furniture.open ) && veh == nullptr &&
357 climb_cost <= 0 ) {
358 layer.state[index] = ASL_CLOSED; // Close it so that next time we won't try to calculate costs
359 continue;
360 }
361
362 newg += cost;
363 if( cost == 0 ) {
364 if( climb_cost > 0 && p_special & PF_CLIMBABLE ) {
365 // Climbing fences
366 newg += climb_cost;
367 } else if( doors && ( terrain.open || furniture.open ) &&
368 ( !terrain.has_flag( "OPENCLOSE_INSIDE" ) || !furniture.has_flag( "OPENCLOSE_INSIDE" ) ||
369 !is_outside( cur ) ) ) {
370 // Only try to open INSIDE doors from the inside
371 // To open and then move onto the tile
372 newg += 4;
373 } else if( veh != nullptr ) {
374 const auto vpobst = vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part();
375 part = vpobst ? vpobst->part_index() : -1;
376 int dummy = -1;
377 if( doors && veh->part_flag( part, VPFLAG_OPENABLE ) &&
378 ( !veh->part_flag( part, "OPENCLOSE_INSIDE" ) ||
379 veh_at_internal( cur, dummy ) == veh ) ) {
380 // Handle car doors, but don't try to path through curtains
381 newg += 10; // One turn to open, 4 to move there
382 } else if( part >= 0 && bash > 0 ) {
383 // Car obstacle that isn't a door
384 // TODO: Account for armor
385 int hp = veh->cpart( part ).hp();
386 if( hp / 20 > bash ) {
387 // Threshold damage thing means we just can't bash this down
388 layer.state[index] = ASL_CLOSED;
389 continue;
390 } else if( hp / 10 > bash ) {
391 // Threshold damage thing means we will fail to deal damage pretty often
392 hp *= 2;
393 }
394
395 newg += 2 * hp / bash + 8 + 4;
396 } else if( part >= 0 ) {
397 if( !doors || !veh->part_flag( part, VPFLAG_OPENABLE ) ) {
398 // Won't be openable, don't try from other sides
399 layer.state[index] = ASL_CLOSED;
400 }
401
402 continue;
403 }
404 } else if( rating > 1 ) {
405 // Expected number of turns to bash it down, 1 turn to move there
406 // and 5 turns of penalty not to trash everything just because we can
407 newg += ( 20 / rating ) + 2 + 10;
408 } else if( rating == 1 ) {
409 // Desperate measures, avoid whenever possible
410 newg += 500;
411 } else {
412 // Unbashable and unopenable from here
413 if( !doors || !terrain.open || !furniture.open ) {
414 // Or anywhere else for that matter
415 layer.state[index] = ASL_CLOSED;
416 }
417
418 continue;
419 }
420 }
421
422 if( trapavoid && p_special & PF_TRAP ) {
423 const auto &ter_trp = terrain.trap.obj();
424 const auto &trp = ter_trp.is_benign() ? tile.get_trap_t() : ter_trp;
425 if( !trp.is_benign() ) {
426 // For now make them detect all traps
427 if( has_zlevels() && terrain.has_flag( TFLAG_NO_FLOOR ) ) {
428 // Special case - ledge in z-levels
429 // Warning: really expensive, needs a cache
430 if( valid_move( p, tripoint( p.xy(), p.z - 1 ), false, true ) ) {
431 tripoint below( p.xy(), p.z - 1 );
432 if( !has_flag( TFLAG_NO_FLOOR, below ) ) {
433 // Otherwise this would have been a huge fall
434 auto &layer = pf.get_layer( p.z - 1 );
435 // From cur, not p, because we won't be walking on air
436 pf.add_point( layer.gscore[parent_index] + 10,
437 layer.score[parent_index] + 10 + 2 * rl_dist( below, t ),
438 cur, below );
439 }
440
441 // Close p, because we won't be walking on it
442 layer.state[index] = ASL_CLOSED;
443 continue;
444 }
445 } else if( trapavoid ) {
446 // Otherwise it's walkable
447 newg += 500;
448 }
449 }
450 }
451
452 if( sharpavoid && p_special & PF_SHARP ) {
453 layer.state[index] = ASL_CLOSED; // Avoid sharp things
454 }
455
456 }
457
458 // If not visited, add as open
459 // If visited, add it only if we can do so with better score
460 if( layer.state[index] == ASL_NONE || newg < layer.gscore[index] ) {
461 pf.add_point( newg, newg + 2 * rl_dist( p, t ), cur, p );
462 }
463 }
464
465 if( !has_zlevels() || !( cur_special & PF_UPDOWN ) || !settings.allow_climb_stairs ) {
466 // The part below is only for z-level pathing
467 continue;
468 }
469
470 const maptile &parent_tile = maptile_at_internal( cur );
471 const auto &parent_terrain = parent_tile.get_ter_t();
472 if( settings.allow_climb_stairs && cur.z > minz && parent_terrain.has_flag( TFLAG_GOES_DOWN ) ) {
473 tripoint dest( cur.xy(), cur.z - 1 );
474 if( vertical_move_destination<TFLAG_GOES_UP>( *this, dest ) ) {
475 auto &layer = pf.get_layer( dest.z );
476 pf.add_point( layer.gscore[parent_index] + 2,
477 layer.score[parent_index] + 2 * rl_dist( dest, t ),
478 cur, dest );
479 }
480 }
481 if( settings.allow_climb_stairs && cur.z < maxz && parent_terrain.has_flag( TFLAG_GOES_UP ) ) {
482 tripoint dest( cur.xy(), cur.z + 1 );
483 if( vertical_move_destination<TFLAG_GOES_DOWN>( *this, dest ) ) {
484 auto &layer = pf.get_layer( dest.z );
485 pf.add_point( layer.gscore[parent_index] + 2,
486 layer.score[parent_index] + 2 * rl_dist( dest, t ),
487 cur, dest );
488 }
489 }
490 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP ) &&
491 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true ) ) {
492 auto &layer = pf.get_layer( cur.z + 1 );
493 for( size_t it = 0; it < 8; it++ ) {
494 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
495 pf.add_point( layer.gscore[parent_index] + 4,
496 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
497 cur, above );
498 }
499 }
500 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP_UP ) &&
501 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true, true ) ) {
502 auto &layer = pf.get_layer( cur.z + 1 );
503 for( size_t it = 0; it < 8; it++ ) {
504 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
505 pf.add_point( layer.gscore[parent_index] + 4,
506 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
507 cur, above );
508 }
509 }
510 if( cur.z > minz && parent_terrain.has_flag( TFLAG_RAMP_DOWN ) &&
511 valid_move( cur, tripoint( cur.xy(), cur.z - 1 ), false, true, true ) ) {
512 auto &layer = pf.get_layer( cur.z - 1 );
513 for( size_t it = 0; it < 8; it++ ) {
514 const tripoint below( cur.x + x_offset[it], cur.y + y_offset[it], cur.z - 1 );
515 pf.add_point( layer.gscore[parent_index] + 4,
516 layer.score[parent_index] + 4 + 2 * rl_dist( below, t ),
517 cur, below );
518 }
519 }
520
521 } while( !done && !pf.empty() );
522
523 if( done ) {
524 ret.reserve( rl_dist( f, t ) * 2 );
525 tripoint cur = t;
526 // Just to limit max distance, in case something weird happens
527 for( int fdist = max_length; fdist != 0; fdist-- ) {
528 const int cur_index = flat_index( cur );
529 const auto &layer = pf.get_layer( cur.z );
530 const tripoint &par = layer.parent[cur_index];
531 if( cur == f ) {
532 break;
533 }
534
535 ret.push_back( cur );
536 // Jumps are acceptable on 1 z-level changes
537 // This is because stairs teleport the player too
538 if( rl_dist( cur, par ) > 1 && std::abs( cur.z - par.z ) != 1 ) {
539 debugmsg( "Jump in our route! %d:%d:%d->%d:%d:%d",
540 cur.x, cur.y, cur.z, par.x, par.y, par.z );
541 return ret;
542 }
543
544 cur = par;
545 }
546
547 std::reverse( ret.begin(), ret.end() );
548 }
549
550 return ret;
551}
bool has_zlevels() const
Definition: map.h:1640
const pathfinding_cache & get_pathfinding_cache_ref(int zlev) const
Definition: map.cpp:8990
point tripoint_to_mount(const tripoint &p) const
Definition: vehicle.cpp:3132
const vehicle_part & cpart(int part_num) const
Definition: vehicle.cpp:7110
bool part_flag(int p, const std::string &f) const
Definition: vehicle.cpp:2913
bool allowed_move(point from, point to) const
Definition: vehicle.cpp:3222
@ TFLAG_GOES_DOWN
Definition: mapdata.h:309
@ TFLAG_GOES_UP
Definition: mapdata.h:310
auto dest(const elevator::tiles &elevator_here, const tripoint &sm_orig, int turns, int movez) -> elevator::tiles
Definition: gates.h:28
Definition: overmap.h:50
bool is_disjoint(const Set1 &set1, const Set2 &set2)
constexpr int flat_index(const tripoint &p)
Definition: pathfinding.cpp:35
@ ASL_CLOSED
Definition: pathfinding.cpp:31
@ ASL_NONE
Definition: pathfinding.cpp:29
@ PF_VEHICLE
Definition: pathfinding.h:11
@ PF_WALL
Definition: pathfinding.h:10
@ PF_CLIMBABLE
Definition: pathfinding.h:15
@ PF_UPDOWN
Definition: pathfinding.h:14
@ PF_TRAP
Definition: pathfinding.h:13
@ PF_SHARP
Definition: pathfinding.h:16
@ PF_SLOW
Definition: pathfinding.h:9
@ hp
Drains HP to recharge.
const trap & get_trap_t() const
Definition: submap.h:264
@ VPFLAG_OPENABLE
Definition: veh_type.h:44

References pathfinding_settings::allow_climb_stairs, pathfinding_settings::allow_open_doors, vehicle::allowed_move(), ASL_CLOSED, ASL_NONE, pathfinding_settings::avoid_rough_terrain, pathfinding_settings::avoid_sharp, pathfinding_settings::avoid_traps, bash(), bash_rating_internal(), pathfinding_settings::bash_strength, pathfinding_settings::climb_cost, clip_to_bounds(), vehicle::cpart(), debugmsg, anonymous_namespace{iexamine_elevator.cpp}::elevator::dest(), detail::digits::done, flat_index(), furniture, maptile::get_furn_t(), get_pathfinding_cache_ref(), maptile::get_ter_t(), maptile::get_trap_t(), has_flag(), has_zlevels(), hp, vehicle_part::hp(), inbounds(), is_disjoint(), is_outside(), line_to(), maptile_at_internal(), pathfinding_settings::max_dist, pathfinding_settings::max_length, move_cost_internal(), vpart_position::obstacle_at_part(), vehicle::part_flag(), PF_CLIMBABLE, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, cata::hash64_detail::ret, rl_dist(), route(), terrain, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, vehicle::tripoint_to_mount(), valid_move(), veh_at_internal(), VPFLAG_OPENABLE, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by add_item_or_charges(), Character::can_mount(), game::handle_action(), game::list_items(), game::look_around(), route(), game::try_get_left_click_action(), and npc::update_path().

◆ save()

void map::save ( )

Add currently loaded submaps (in grid) to the mapbuffer.

They will than be stored by that class and can be loaded from that class. This can be called several times, the mapbuffer takes care of adding the same submap several times. It should only be called after the map has been loaded. Submaps that have been loaded from the mapbuffer (and not generated) are already stored in the mapbuffer. TODO: determine if this is really needed? Submaps are already in the mapbuffer if they have been loaded from disc and the are added by map::generate, too. So when do they not appear in the mapbuffer?

Definition at line 6735 of file map.cpp.

6736{
6737 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6738 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6739 if( zlevels ) {
6740 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
6741 saven( tripoint( gridx, gridy, gridz ) );
6742 }
6743 } else {
6744 saven( tripoint( gridx, gridy, abs_sub.z ) );
6745 }
6746 }
6747 }
6748}

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, saven(), tripoint::z, and zlevels.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), defense_game::init_map(), mission_start::kill_horde_master(), talk_function::loot_building(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), game::save_maps(), and debug_menu::spawn_nested_mapgen().

◆ saven()

void map::saven ( const tripoint grid)
protected

Definition at line 7078 of file map.cpp.

7079{
7080 dbg( DL::Debug ) << "map::saven( world=" << abs_sub << ", grid=" << grid << " )";
7081 const int gridn = get_nonant( grid );
7082 submap *submap_to_save = getsubmap( gridn );
7083 if( submap_to_save == nullptr || submap_to_save->get_ter( point_zero ) == t_null ) {
7084 // This is a serious error and should be signaled as soon as possible
7085 debugmsg( "map::saven grid (%s) %s!", grid.to_string(),
7086 submap_to_save == nullptr ? "null" : "uninitialized" );
7087 return;
7088 }
7089
7090 const tripoint abs = abs_sub.xy() + grid;
7091
7092 if( !zlevels && grid.z != abs_sub.z ) {
7093 debugmsg( "Tried to save submap (%d,%d,%d) as (%d,%d,%d), which isn't supported in non-z-level builds",
7094 abs.x, abs.y, abs_sub.z, abs.x, abs.y, grid.z );
7095 }
7096
7097 dbg( DL::Debug ) << "map::saven abs: " << abs << " gridn: " << gridn;
7098
7099 // An edge case: restock_fruits relies on last_touched, so we must call it before save
7100 if( season_of_year( calendar::turn ) != season_of_year( submap_to_save->last_touched ) ) {
7101 const time_duration time_since_last_actualize = calendar::turn - submap_to_save->last_touched;
7102 for( int x = 0; x < SEEX; x++ ) {
7103 for( int y = 0; y < SEEY; y++ ) {
7104 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7105 restock_fruits( pnt, time_since_last_actualize );
7106 }
7107 }
7108 }
7109
7110 submap_to_save->last_touched = calendar::turn;
7111 MAPBUFFER.add_submap( abs, submap_to_save );
7112}
bool add_submap(const tripoint &p, std::unique_ptr< submap > &sm)
Add a new submap to the buffer.
Definition: mapbuffer.cpp:50
@ Debug
Debug information (default: disabled).

References abs_sub, mapbuffer::add_submap(), dbg, Debug, debugmsg, get_nonant(), submap::get_ter(), getsubmap(), grid, submap::last_touched, MAPBUFFER, point_zero, restock_fruits(), season_of_year(), SEEX, SEEY, sm_to_ms_copy(), t_null, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by generate(), and save().

◆ scent_blockers()

void map::scent_blockers ( std::array< std::array< char, MAPSIZE_X >, MAPSIZE_Y > &  scent_transfer,
point  min,
point  max 
)

Build the map of scent-resistant tiles.

Should be way faster than if done in game.cpp using public map functions.

Definition at line 8702 of file map.cpp.

8704{
8705 auto reduce = TFLAG_REDUCE_SCENT;
8706 auto block = TFLAG_NO_SCENT;
8707 auto fill_values = [&]( const tripoint & gp, const submap * sm, point lp ) {
8708 // We need to generate the x/y coordinates, because we can't get them "for free"
8709 const point p = lp + sm_to_ms_copy( gp.xy() );
8710 if( sm->get_ter( lp ).obj().has_flag( block ) ) {
8711 scent_transfer[p.x][p.y] = 0;
8712 } else if( sm->get_ter( lp ).obj().has_flag( reduce ) ||
8713 sm->get_furn( lp ).obj().has_flag( reduce ) ) {
8714 scent_transfer[p.x][p.y] = 1;
8715 } else {
8716 scent_transfer[p.x][p.y] = 5;
8717 }
8718
8719 return ITER_CONTINUE;
8720 };
8721
8722 function_over( tripoint( min, abs_sub.z ), tripoint( max, abs_sub.z ), fill_values );
8723
8724 const inclusive_rectangle<point> local_bounds( min, max );
8725
8726 // Now vehicles
8727
8728 auto vehs = get_vehicles();
8729 for( auto &wrapped_veh : vehs ) {
8730 vehicle &veh = *( wrapped_veh.v );
8731 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OBSTACLE ) ) {
8732 const tripoint part_pos = vp.pos();
8733 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8734 scent_transfer[part_pos.x][part_pos.y] = 1;
8735 }
8736 }
8737
8738 // Doors, but only the closed ones
8739 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OPENABLE ) ) {
8740 if( vp.part().open ) {
8741 continue;
8742 }
8743
8744 const tripoint part_pos = vp.pos();
8745 if( local_bounds.contains( part_pos.xy() ) && scent_transfer[part_pos.x][part_pos.y] == 5 ) {
8746 scent_transfer[part_pos.x][part_pos.y] = 1;
8747 }
8748 }
8749 }
8750}
void function_over(const tripoint &start, const tripoint &end, Functor fun) const
Runs a functor over given submaps over submaps in the area, getting next submap only when the current...
Definition: map.cpp:8648
@ TFLAG_REDUCE_SCENT
Definition: mapdata.h:279
@ TFLAG_NO_SCENT
Definition: mapdata.h:285
@ VPFLAG_OBSTACLE
Definition: veh_type.h:42

References abs_sub, inclusive_rectangle< Point, >::contains(), function_over(), vehicle::get_any_parts(), get_vehicles(), ITER_CONTINUE, coords::sm, sm_to_ms_copy(), TFLAG_NO_SCENT, TFLAG_REDUCE_SCENT, VPFLAG_OBSTACLE, VPFLAG_OPENABLE, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by scent_map::update().

◆ sees() [1/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range 
) const

Returns whether F sees T with a view range of range.

Definition at line 6270 of file map.cpp.

6271{
6272 int dummy = 0;
6273 return sees( F, T, range, dummy );
6274}

References range, and sees().

Referenced by find_clear_path(), sees(), shake_vehicle(), shoot(), and spawn_monsters_submap_group().

◆ sees() [2/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range,
int &  bresenham_slope 
) const
private

Don't expose the slope adjust outside map functions.

This one is internal-only, we don't want to expose the slope tweaking ickiness outside the map class.

Parameters
FThing doing the seeing
TThing being seen
rangeVision range of F
bresenham_slopeIndicates the start offset of Bresenham line used to connect the two points, and may subsequently be used to form a path between them. Set to zero if the function returns false.

Definition at line 6279 of file map.cpp.

6281{
6282 if( ( range >= 0 && range < rl_dist( F, T ) ) ||
6283 !inbounds( T ) ) {
6284 bresenham_slope = 0;
6285 return false; // Out of range!
6286 }
6287 // Cannonicalize the order of the tripoints so the cache is reflexive.
6288 const tripoint &min = F < T ? F : T;
6289 const tripoint &max = !( F < T ) ? F : T;
6290 // A little gross, just pack the values into a point.
6291 const point key(
6292 min.x << 16 | min.y << 8 | ( min.z + OVERMAP_DEPTH ),
6293 max.x << 16 | max.y << 8 | ( max.z + OVERMAP_DEPTH )
6294 );
6295 char cached = skew_vision_cache.get( key, -1 );
6296 if( cached >= 0 ) {
6297 return cached > 0;
6298 }
6299
6300 bool visible = true;
6301
6302 // Ugly `if` for now
6303 if( !fov_3d || F.z == T.z ) {
6304
6305 point last_point = F.xy();
6306 bresenham( F.xy(), T.xy(), bresenham_slope,
6307 [this, &visible, &T, &last_point]( point new_point ) {
6308 // Exit before checking the last square, it's still visible even if opaque.
6309 if( new_point.x == T.x && new_point.y == T.y ) {
6310 return false;
6311 }
6312 if( !this->is_transparent( tripoint( new_point, T.z ) ) ||
6313 obscured_by_vehicle_rotation( tripoint( last_point, T.z ), tripoint( new_point, T.z ) ) ) {
6314 visible = false;
6315 return false;
6316 }
6317 last_point = new_point;
6318 return true;
6319 } );
6320 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6321 return visible;
6322 }
6323
6324 tripoint last_point = F;
6325 bresenham( F, T, bresenham_slope, 0,
6326 [this, &visible, &T, &last_point]( const tripoint & new_point ) {
6327 // Exit before checking the last square if it's not a vertical transition,
6328 // it's still visible even if opaque.
6329 if( new_point == T && last_point.z == T.z ) {
6330 return false;
6331 }
6332
6333 // TODO: Allow transparent floors (and cache them!)
6334 if( new_point.z == last_point.z ) {
6335 if( !this->is_transparent( new_point ) || obscured_by_vehicle_rotation( last_point, new_point ) ) {
6336 visible = false;
6337 return false;
6338 }
6339 } else {
6340 const int max_z = std::max( new_point.z, last_point.z );
6341 if( ( has_floor_or_support( {new_point.xy(), max_z} ) ||
6342 !is_transparent( {new_point.xy(), last_point.z} ) ) &&
6343 ( has_floor_or_support( {last_point.xy(), max_z} ) ||
6344 !is_transparent( {last_point.xy(), new_point.z} ) ) ) {
6345 visible = false;
6346 return false;
6347 }
6348 }
6349
6350 last_point = new_point;
6351 return true;
6352 } );
6353 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6354 return visible;
6355}

References bresenham(), fov_3d, inbounds(), obscured_by_vehicle_rotation(), OVERMAP_DEPTH, range, rl_dist(), skew_vision_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

◆ sees_some_items() [1/2]

bool map::sees_some_items ( const tripoint p,
const Creature who 
) const

Check if creature can see some items at p.

Includes:

  • check for items at this location (has_items(p))
  • check for SEALED flag (sealed furniture/terrain makes items not visible under any circumstances).
  • check for CONTAINER flag (makes items only visible when the creature is at p or at an adjacent square).

Definition at line 4856 of file map.cpp.

4857{
4858 // Can only see items if there are any items.
4859 return has_items( p ) && could_see_items( p, who.pos() );
4860}

References could_see_items(), has_items(), and Creature::pos().

Referenced by game::butcher(), editmap::draw_main_ui_overlay(), draw_maptile(), game::find_nearby_items(), and game::print_items_info().

◆ sees_some_items() [2/2]

bool map::sees_some_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4862 of file map.cpp.

4863{
4864 return has_items( p ) && could_see_items( p, from );
4865}

References could_see_items(), and has_items().

◆ set() [1/2]

void map::set ( const tripoint p,
const ter_id new_terrain,
const furn_id new_furniture 
)

Definition at line 1384 of file map.cpp.

1385{
1386 furn_set( p, new_furniture );
1387 ter_set( p, new_terrain );
1388}

References furn_set(), and ter_set().

Referenced by farm_action(), talk_function::field_plant(), and mapgen_function_json_base::formatted_set_incredibly_simple().

◆ set() [2/2]

void map::set ( point  p,
const ter_id new_terrain,
const furn_id new_furniture 
)
inline

Definition at line 774 of file map.h.

774 {
775 furn_set( p, new_furniture );
776 ter_set( p, new_terrain );
777 }

References furn_set(), and ter_set().

◆ set_abs_sub()

void map::set_abs_sub ( const tripoint p)
protected

Sets abs_sub, see there.

Uses the same coordinate system as abs_sub.

Definition at line 8428 of file map.cpp.

8429{
8430 abs_sub = p;
8431}

References abs_sub.

Referenced by fake_map::fake_map(), generate(), load(), shift(), and vertical_shift().

◆ set_field_age()

time_duration map::set_field_age ( const tripoint p,
const field_type_id type,
const time_duration age,
bool  isoffset = false 
)

Set age of field entry at point.

Parameters
pLocation of field
typeID of field
ageNew age of specified field
isoffsetIf true, the given age value is added to the existing value, if false, the existing age is ignored and overridden.
Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5460 of file map.cpp.

5462{
5463 if( field_entry *const field_ptr = get_field( p, type ) ) {
5464 return field_ptr->set_field_age( ( isoffset ? field_ptr->get_field_age() : 0_turns ) + age );
5465 }
5466 return -1_turns;
5467}

References get_field(), and type.

Referenced by game::grabbed_furn_move(), mod_field_age(), and game::walk_move().

◆ set_field_intensity()

int map::set_field_intensity ( const tripoint p,
const field_type_id type,
int  new_intensity,
bool  isoffset = false 
)

Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Parameters
pLocation of field
typeID of field
new_intensityNew intensity of field
isoffsetIf true, the given new_intensity value is added to the existing value, if false, the existing intensity is ignored and overridden.
Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5473 of file map.cpp.

5476{
5477 field_entry *field_ptr = get_field( p, type );
5478 if( field_ptr != nullptr ) {
5479 int adj = ( isoffset ? field_ptr->get_field_intensity() : 0 ) + new_intensity;
5480 if( adj > 0 ) {
5481 field_ptr->set_field_intensity( adj );
5482 return adj;
5483 } else {
5484 remove_field( p, type );
5485 return 0;
5486 }
5487 } else if( 0 + new_intensity > 0 ) {
5488 return add_field( p, type, new_intensity ) ? new_intensity : 0;
5489 }
5490
5491 return 0;
5492}

References add_field(), get_field(), field_entry::get_field_intensity(), remove_field(), field_entry::set_field_intensity(), and type.

Referenced by game::grabbed_furn_move(), mod_field_intensity(), and game::walk_move().

◆ set_floor_cache_dirty()

void map::set_floor_cache_dirty ( const int  zlev)

Definition at line 236 of file map.cpp.

237{
238 if( inbounds_z( zlev ) ) {
239 get_cache( zlev ).floor_cache_dirty = true;
240 }
241}

References level_cache::floor_cache_dirty, get_cache(), and inbounds_z().

Referenced by furn_set(), loadn(), on_vehicle_moved(), DefaultRemovePartHandler::set_floor_cache_dirty(), and ter_set().

◆ set_graffiti()

void map::set_graffiti ( const tripoint p,
const std::string &  contents 
)

Definition at line 7949 of file map.cpp.

7950{
7951 if( !inbounds( p ) ) {
7952 return;
7953 }
7954 point l;
7955 submap *const current_submap = get_submap_at( p, l );
7956 current_submap->set_graffiti( l, contents );
7957}
void set_graffiti(point p, const std::string &new_graffiti)
Definition: submap.cpp:133

References get_submap_at(), inbounds(), and submap::set_graffiti().

Referenced by jmapgen_graffiti::apply().

◆ set_memory_seen_cache_dirty()

void map::set_memory_seen_cache_dirty ( const tripoint p)

Definition at line 8982 of file map.cpp.

8983{
8984 const int offset = p.x + p.y * MAPSIZE_Y;
8985 if( offset >= 0 && offset < MAPSIZE_X * MAPSIZE_Y ) {
8986 get_cache( p.z ).map_memory_seen_cache.reset( offset );
8987 }
8988}

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_X, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by furn_set(), and ter_set().

◆ set_outside_cache_dirty()

void map::set_outside_cache_dirty ( const int  zlev)

Definition at line 222 of file map.cpp.

223{
224 if( inbounds_z( zlev ) ) {
225 get_cache( zlev ).outside_cache_dirty = true;
226 }
227}

References get_cache(), inbounds_z(), and level_cache::outside_cache_dirty.

Referenced by draw_fill_background(), furn_set(), loadn(), on_vehicle_moved(), ter_set(), and game::vertical_shift().

◆ set_pathfinding_cache_dirty()

void map::set_pathfinding_cache_dirty ( int  zlev)

Definition at line 8945 of file map.cpp.

8946{
8947 if( inbounds_z( zlev ) ) {
8948 get_pathfinding_cache( zlev ).dirty = true;
8949 }
8950}

References pathfinding_cache::dirty, get_pathfinding_cache(), and inbounds_z().

Referenced by add_field(), draw_fill_background(), furn_set(), loadn(), on_vehicle_moved(), remove_field(), and ter_set().

◆ set_radiation() [1/2]

void map::set_radiation ( const tripoint p,
int  value 
)

Definition at line 4166 of file map.cpp.

4167{
4168 if( !inbounds( p ) ) {
4169 return;
4170 }
4171
4172 point l;
4173 submap *const current_submap = get_submap_at( p, l );
4174
4175 current_submap->set_radiation( l, value );
4176}

References get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by jmapgen_setmap::apply(), create_anomaly(), draw_lab(), mapgen_crater(), mapgen_null(), mapgen_test(), and set_radiation().

◆ set_radiation() [2/2]

void map::set_radiation ( point  p,
const int  value 
)
inline

Definition at line 1156 of file map.h.

1156 {
1157 set_radiation( tripoint( p, abs_sub.z ), value );
1158 }

References abs_sub, set_radiation(), and tripoint::z.

◆ set_seen_cache_dirty() [1/2]

void map::set_seen_cache_dirty ( const int  zlevel)

Definition at line 243 of file map.cpp.

244{
245 if( inbounds_z( zlevel ) ) {
246 level_cache &cache = get_cache( zlevel );
247 cache.seen_cache_dirty = true;
248 }
249}

References get_cache(), inbounds_z(), and level_cache::seen_cache_dirty.

◆ set_seen_cache_dirty() [2/2]

void map::set_seen_cache_dirty ( const tripoint  change_location)

Definition at line 208 of file map.cpp.

209{
210 if( inbounds( change_location ) ) {
211 level_cache &cache = get_cache( change_location.z );
212 if( cache.seen_cache_dirty ) {
213 return;
214 }
215 if( cache.seen_cache[change_location.x][change_location.y] != 0.0 ||
216 cache.camera_cache[change_location.x][change_location.y] != 0.0 ) {
217 cache.seen_cache_dirty = true;
218 }
219 }
220}

References level_cache::camera_cache, get_cache(), inbounds(), level_cache::seen_cache, level_cache::seen_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_field(), draw_fill_background(), furn_set(), loadn(), process_fields_in_submap(), remove_field(), avatar::set_movement_mode(), ter_set(), and weather_manager::update_weather().

◆ set_signage()

void map::set_signage ( const tripoint p,
const std::string &  message 
) const

Definition at line 4131 of file map.cpp.

4132{
4133 if( !inbounds( p ) ) {
4134 return;
4135 }
4136
4137 point l;
4138 submap *const current_submap = get_submap_at( p, l );
4139
4140 current_submap->set_signage( l, message );
4141}
void set_signage(point p, const std::string &s)
Definition: submap.cpp:173
std::string message
Definition: mapgen.cpp:420

References get_submap_at(), inbounds(), mapgen_defer::message, and submap::set_signage().

Referenced by jmapgen_sign::apply(), MapExtras::mx_grave(), and MapExtras::mx_minefield().

◆ set_suspension_cache_dirty()

void map::set_suspension_cache_dirty ( const int  zlev)

Definition at line 229 of file map.cpp.

230{
231 if( inbounds_z( zlev ) ) {
232 get_cache( zlev ).suspension_cache_dirty = true;
233 }
234}

References get_cache(), inbounds_z(), and level_cache::suspension_cache_dirty.

Referenced by loadn(), and ter_set().

◆ set_temperature() [1/2]

void map::set_temperature ( const tripoint p,
int  temperature 
)

Definition at line 4200 of file map.cpp.

4201{
4202 if( !inbounds( p ) ) {
4203 return;
4204 }
4205
4206 get_submap_at( p )->set_temperature( new_temperature );
4207}
void set_temperature(int new_temperature)
Definition: submap.h:169

References get_submap_at(), inbounds(), and submap::set_temperature().

Referenced by draw_lab(), and set_temperature().

◆ set_temperature() [2/2]

void map::set_temperature ( point  p,
int  new_temperature 
)
inline

Definition at line 1173 of file map.h.

1173 {
1174 set_temperature( tripoint( p, abs_sub.z ), new_temperature );
1175 }

References abs_sub, set_temperature(), and tripoint::z.

◆ set_transparency_cache_dirty() [1/2]

void map::set_transparency_cache_dirty ( const int  zlev)

Sets a dirty flag on the a given cache.

If this isn't set, it's just assumed that the cache hasn't changed and doesn't need to be updated.

Definition at line 201 of file map.cpp.

202{
203 if( inbounds_z( zlev ) ) {
205 }
206}

References get_cache(), inbounds_z(), and level_cache::transparency_cache_dirty.

Referenced by add_field(), draw_fill_background(), furn_set(), loadn(), on_vehicle_moved(), process_fields_in_submap(), remove_field(), ter_set(), weather_manager::update_weather(), and game::vertical_shift().

◆ set_transparency_cache_dirty() [2/2]

void map::set_transparency_cache_dirty ( const tripoint p)

Definition at line 251 of file map.cpp.

252{
253 if( inbounds( p ) ) {
254 const tripoint smp = ms_to_sm_copy( p );
255 get_cache( smp.z ).transparency_cache_dirty.set( smp.x * MAPSIZE + smp.y );
256 }
257}

References get_cache(), inbounds(), MAPSIZE, ms_to_sm_copy(), level_cache::transparency_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

◆ setsubmap()

void map::setsubmap ( size_t  grididx,
submap smap 
)
protected

Set the submap pointer in grid at the give index.

This is the inverse of getsubmap, any existing pointer is overwritten. The index must be valid. The given submap pointer must not be null.

Definition at line 8447 of file map.cpp.

8448{
8449 if( grididx >= grid.size() ) {
8450 debugmsg( "Tried to access invalid grid index %d", grididx );
8451 return;
8452 } else if( smap == nullptr ) {
8453 debugmsg( "Tried to set NULL submap pointer at index %d", grididx );
8454 return;
8455 }
8456 grid[grididx] = smap;
8457}

References debugmsg, and grid.

Referenced by copy_grid(), fake_map::fake_map(), generate(), and loadn().

◆ shake_vehicle()

units::angle map::shake_vehicle ( vehicle veh,
int  velocity_before,
units::angle  direction 
)
Strength reduces chance of being thrown from your seat when not wearing a seatbelt Strength reduces chance of being thrown from your seat when not wearing a seatbelt Dexterity reduces chance of losing control of vehicle when shaken Driving reduces chance of losing control of vehicle when shaken Strength reduces distance thrown from seat in a vehicle impact

Definition at line 1651 of file vehicle_move.cpp.

1653{
1654 const int d_vel = std::abs( veh.velocity - velocity_before ) / 100;
1655
1656 std::vector<rider_data> riders = veh.get_riders();
1657
1658 units::angle coll_turn = 0_degrees;
1659 for( const rider_data &r : riders ) {
1660 const int ps = r.prt;
1661 Creature *rider = r.psg;
1662 if( rider == nullptr ) {
1663 debugmsg( "throw passenger: empty passenger at part %d", ps );
1664 continue;
1665 }
1666
1667 const tripoint part_pos = veh.global_part_pos3( ps );
1668 if( rider->pos() != part_pos ) {
1669 debugmsg( "throw passenger: passenger at %d,%d,%d, part at %d,%d,%d",
1670 rider->posx(), rider->posy(), rider->posz(),
1671 part_pos.x, part_pos.y, part_pos.z );
1673 continue;
1674 }
1675
1676 player *psg = dynamic_cast<player *>( rider );
1677 monster *pet = dynamic_cast<monster *>( rider );
1678
1679 bool throw_from_seat = false;
1680 int move_resist = 1;
1681 if( psg ) {
1682 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1683 move_resist = psg->str_cur * 150 + 500;
1684 } else {
1685 int pet_resist = 0;
1686 if( pet != nullptr ) {
1687 pet_resist = static_cast<int>( to_kilogram( pet->get_weight() ) * 200 );
1688 }
1689 move_resist = std::max( 100, pet_resist );
1690 }
1691 if( veh.part_with_feature( ps, VPFLAG_SEATBELT, true ) == -1 ) {
1692 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1693 throw_from_seat = d_vel * rng( 80, 120 ) > move_resist;
1694 }
1695
1696 // Damage passengers if d_vel is too high
1697 if( !throw_from_seat && ( 10 * d_vel ) > 6 * rng( 50, 100 ) ) {
1698 const int dmg = d_vel * rng( 70, 100 ) / 400;
1699 if( psg ) {
1700 psg->hurtall( dmg, nullptr );
1702 _( "You take %d damage by the power of the impact!" ),
1703 _( "<npcname> takes %d damage by the power of the "
1704 "impact!" ), dmg );
1705 } else {
1706 pet->apply_damage( nullptr, bodypart_id( "torso" ), dmg );
1707 }
1708 }
1709
1710 if( psg && veh.player_in_control( *psg ) ) {
1711 const int lose_ctrl_roll = rng( 0, d_vel );
1712 ///\EFFECT_DEX reduces chance of losing control of vehicle when shaken
1713
1714 ///\EFFECT_DRIVING reduces chance of losing control of vehicle when shaken
1715 if( lose_ctrl_roll > psg->dex_cur * 2 + psg->get_skill_level( skill_driving ) * 3 ) {
1717 _( "You lose control of the %s." ),
1718 _( "<npcname> loses control of the %s." ), veh.name );
1719 int turn_amount = rng( 1, 3 ) * std::sqrt( std::abs( veh.velocity ) ) / 30;
1720 if( turn_amount < 1 ) {
1721 turn_amount = 1;
1722 }
1723 units::angle turn_angle = std::min( turn_amount * 15_degrees, 120_degrees );
1724 coll_turn = one_in( 2 ) ? turn_angle : -turn_angle;
1725 }
1726 }
1727
1728 if( throw_from_seat ) {
1729 if( psg ) {
1731 _( "You are hurled from the %s's seat by "
1732 "the power of the impact!" ),
1733 _( "<npcname> is hurled from the %s's seat by "
1734 "the power of the impact!" ), veh.name );
1735 unboard_vehicle( part_pos );
1736 } else if( get_player_character().sees( part_pos ) ) {
1737 add_msg( m_bad, _( "The %s is hurled from %s's by the power of the impact!" ),
1738 pet->disp_name(), veh.name );
1739 }
1740 ///\EFFECT_STR reduces distance thrown from seat in a vehicle impact
1741 g->fling_creature( rider, direction + rng_float( -30_degrees, 30_degrees ),
1742 std::max( 10, d_vel - move_resist / 100 ) );
1743 }
1744 }
1745
1746 return coll_turn;
1747}
int dex_cur
Definition: character.h:265
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3350
units::mass get_weight() const override
Definition: monster.cpp:2740
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:533
@ VPFLAG_SEATBELT
Definition: veh_type.h:45
static const skill_id skill_driving("driving")

References _, add_msg(), player::add_msg_player_or_npc(), monster::apply_damage(), debugmsg, Character::dex_cur, monster::disp_name(), g, get_player_character(), vehicle::get_riders(), Character::get_skill_level(), monster::get_weight(), vehicle::global_part_pos3(), Character::hurtall(), m_bad, m_warning, vehicle::name, one_in(), vehicle::part(), vehicle::part_with_feature(), vehicle_part::passenger_flag, vehicle::player_in_control(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::remove_flag(), rng(), rng_float(), sees(), skill_driving, Character::str_cur, units::to_kilogram(), unboard_vehicle(), vehicle::velocity, VPFLAG_SEATBELT, tripoint::x, tripoint::y, and tripoint::z.

Referenced by move_vehicle().

◆ shift()

void map::shift ( point  s)

Shift the map along the vector s.

This is like loading the map with coordinates derived from the current position of the map (abs_sub) plus the shift vector. Note: the map must have been loaded before this can be called.

Definition at line 6907 of file map.cpp.

6908{
6909 // Special case of 0-shift; refresh the map
6910 if( sp == point_zero ) {
6911 return; // Skip this?
6912 }
6913
6914 if( std::abs( sp.x ) > 1 || std::abs( sp.y ) > 1 ) {
6915 debugmsg( "map::shift called with a shift of more than one submap" );
6916 }
6917
6918 const tripoint abs = get_abs_sub();
6919
6920 set_abs_sub( abs + sp );
6921
6922 // if player is in vehicle, (s)he must be shifted with vehicle too
6923 if( g->u.in_vehicle ) {
6924 g->u.setx( g->u.posx() - sp.x * SEEX );
6925 g->u.sety( g->u.posy() - sp.y * SEEY );
6926 }
6927
6928 g->shift_destination_preview( point( -sp.x * SEEX, -sp.y * SEEY ) );
6929
6930 shift_traps( tripoint( sp, 0 ) );
6931
6932 vehicle *remoteveh = g->remoteveh();
6933
6934 const int zmin = zlevels ? -OVERMAP_DEPTH : abs.z;
6935 const int zmax = zlevels ? OVERMAP_HEIGHT : abs.z;
6936 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6937 for( vehicle *veh : get_cache( gridz ).vehicle_list ) {
6938 veh->zones_dirty = true;
6939 }
6940 }
6941
6942 constexpr half_open_rectangle<point> boundaries_2d( point_zero, point( MAPSIZE_Y, MAPSIZE_X ) );
6943 const point shift_offset_pt( -sp.x * SEEX, -sp.y * SEEY );
6944
6945 // Clear vehicle list and rebuild after shift
6947 // Shift the map sx submaps to the right and sy submaps down.
6948 // sx and sy should never be bigger than +/-1.
6949 // absx and absy are our position in the world, for saving/loading purposes.
6950 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6951 clear_vehicle_list( gridz );
6952 shift_bitset_cache<MAPSIZE_X, SEEX>( get_cache( gridz ).map_memory_seen_cache, sp );
6953 shift_bitset_cache<MAPSIZE, 1>( get_cache( gridz ).field_cache, sp );
6954 if( sp.x >= 0 ) {
6955 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6956 if( sp.y >= 0 ) {
6957 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6958 if( ( sp.x > 0 && gridx == 0 ) || ( sp.y > 0 && gridy == 0 ) ) {
6959 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6960 }
6961 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y < my_MAPSIZE ) {
6962 copy_grid( tripoint( gridx, gridy, gridz ),
6963 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6964 update_vehicle_list( get_submap_at_grid( {gridx, gridy, gridz} ), gridz );
6965 } else {
6966 loadn( tripoint( gridx, gridy, gridz ), true );
6967 }
6968 }
6969 } else { // sy < 0; work through it backwards
6970 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6971 if( ( sp.x > 0 && gridx == 0 ) || gridy == my_MAPSIZE - 1 ) {
6972 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6973 }
6974 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y >= 0 ) {
6975 copy_grid( tripoint( gridx, gridy, gridz ),
6976 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6977 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6978 } else {
6979 loadn( tripoint( gridx, gridy, gridz ), true );
6980 }
6981 }
6982 }
6983 }
6984 } else { // sx < 0; work through it backwards
6985 for( int gridx = my_MAPSIZE - 1; gridx >= 0; gridx-- ) {
6986 if( sp.y >= 0 ) {
6987 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6988 if( gridx == my_MAPSIZE - 1 || ( sp.y > 0 && gridy == 0 ) ) {
6989 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6990 }
6991 if( gridx + sp.x >= 0 && gridy + sp.y < my_MAPSIZE ) {
6992 copy_grid( tripoint( gridx, gridy, gridz ),
6993 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6994 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6995 } else {
6996 loadn( tripoint( gridx, gridy, gridz ), true );
6997 }
6998 }
6999 } else { // sy < 0; work through it backwards
7000 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
7001 if( gridx == my_MAPSIZE - 1 || gridy == my_MAPSIZE - 1 ) {
7002 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
7003 }
7004 if( gridx + sp.x >= 0 && gridy + sp.y >= 0 ) {
7005 copy_grid( tripoint( gridx, gridy, gridz ),
7006 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
7007 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
7008 } else {
7009 loadn( tripoint( gridx, gridy, gridz ), true );
7010 }
7011 }
7012 }
7013 }
7014 }
7015 }
7016 if( zlevels ) {
7017 //Go through the generated maps and fill in the roofs
7018 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
7019 if( sp.x > 0 ) {
7020 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
7021 add_roofs( {my_MAPSIZE - 1, gridy, gridz} );
7022 }
7023 } else if( sp.x < 0 ) {
7024 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
7025 add_roofs( {0, gridy, gridz} );
7026 }
7027 }
7028
7029 if( sp.y > 0 ) {
7030 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
7031 add_roofs( {gridx, my_MAPSIZE - 1, gridz} );
7032 }
7033 } else if( sp.y < 0 ) {
7034 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
7035 add_roofs( {gridx, 0, gridz} );
7036 }
7037 }
7038 }
7039 }
7040
7042
7043 g->setremoteveh( remoteveh );
7044
7045 if( !support_cache_dirty.empty() ) {
7046 shift_tripoint_set( support_cache_dirty, shift_offset_pt, boundaries_2d );
7047 }
7048}
void copy_grid(const tripoint &to, const tripoint &from)
Definition: map.cpp:7649
void shift_traps(const tripoint &shift)
As part of the map shifting, this shifts the trap locations stored in traplocs.
Definition: map.cpp:6775
template void shift_bitset_cache< MAPSIZE_X, SEEX >(std::bitset< MAPSIZE_X *MAPSIZE_X > &cache, point s)
static void shift_tripoint_set(std::set< tripoint > &set, point offset, const half_open_rectangle< point > &boundaries)
Definition: map.cpp:6834
template void shift_bitset_cache< MAPSIZE, 1 >(std::bitset< MAPSIZE *MAPSIZE > &cache, point s)
int remoteveh(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:8226

References add_roofs(), clear_vehicle_cache(), clear_vehicle_list(), copy_grid(), debugmsg, g, get_abs_sub(), get_cache(), get_submap_at_grid(), loadn(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, iuse::remoteveh(), reset_vehicle_cache(), SEEX, SEEY, set_abs_sub(), shift_bitset_cache< MAPSIZE, 1 >(), shift_bitset_cache< MAPSIZE_X, SEEX >(), shift_traps(), shift_tripoint_set(), submaps_with_active_items, support_cache_dirty, update_vehicle_list(), point::x, point::y, and zlevels.

Referenced by shift_traps(), and game::update_map().

◆ shift_traps()

void map::shift_traps ( const tripoint shift)
protected

As part of the map shifting, this shifts the trap locations stored in traplocs.

Parameters
shiftThe amount shifting in submap, the same as go into shift.

Definition at line 6775 of file map.cpp.

6776{
6777 // Offset needs to have sign opposite to shift direction
6778 const tripoint offset( -shift.x * SEEX, -shift.y * SEEY, -shift.z );
6779 for( auto iter = field_furn_locs.begin(); iter != field_furn_locs.end(); ) {
6780 tripoint &pos = *iter;
6781 pos += offset;
6782 if( inbounds( pos ) ) {
6783 ++iter;
6784 } else {
6785 iter = field_furn_locs.erase( iter );
6786 }
6787 }
6788 for( auto &traps : traplocs ) {
6789 for( auto iter = traps.begin(); iter != traps.end(); ) {
6790 tripoint &pos = *iter;
6791 pos += offset;
6792 if( inbounds( pos ) ) {
6793 ++iter;
6794 } else {
6795 // Theoretical enhancement: if this is not the last entry of the vector,
6796 // move the last entry into pos and remove the last entry instead of iter.
6797 // This would avoid moving all the remaining entries.
6798 iter = traps.erase( iter );
6799 }
6800 }
6801 }
6802}
void shift(point s)
Shift the map along the vector s.
Definition: map.cpp:6907

References field_furn_locs, inbounds(), SEEX, SEEY, shift(), and traplocs.

Referenced by shift().

◆ shift_vehicle_z()

void map::shift_vehicle_z ( vehicle veh,
int  z_shift 
)

Definition at line 6861 of file map.cpp.

6862{
6863
6864 tripoint src = veh.global_pos3();
6865 tripoint dst = src + tripoint_above * z_shift;
6866
6867 submap *src_submap = get_submap_at( src );
6868 submap *dst_submap = get_submap_at( dst );
6869
6870 int our_i = -1;
6871 for( size_t i = 0; i < src_submap->vehicles.size(); i++ ) {
6872 if( src_submap->vehicles[i].get() == &veh ) {
6873 our_i = i;
6874 break;
6875 }
6876 }
6877
6878 if( our_i == -1 ) {
6879 debugmsg( "shift_vehicle [%s] failed could not find vehicle", veh.name );
6880 return;
6881 }
6882
6883 for( auto &prt : veh.get_all_parts() ) {
6884 prt.part().precalc[0].z -= z_shift;
6885 }
6886
6887 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
6888 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
6889 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
6890 src_submap->vehicles.erase( src_submap_veh_it );
6891 dst_submap->is_uniform = false;
6893
6894 update_vehicle_list( dst_submap, dst.z );
6895
6896 level_cache &ch = get_cache( src.z );
6897 for( const vehicle *elem : ch.vehicle_list ) {
6898 if( elem == &veh ) {
6899 ch.vehicle_list.erase( &veh );
6900 ch.zone_vehicles.erase( &veh );
6901 break;
6902 }
6903 }
6904
6905}

References debugmsg, vehicle::get_all_parts(), get_cache(), get_submap_at(), vehicle::global_pos3(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), vehicle::name, SEEX, SEEY, vehicle::set_submap_moved(), tripoint_above, update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

◆ shoot()

void map::shoot ( const tripoint p,
projectile proj,
bool  hit_items 
)

Definition at line 3822 of file map.cpp.

3823{
3824 float initial_damage = 0.0;
3825 for( const damage_unit &dam : proj.impact ) {
3826 initial_damage += dam.amount * dam.damage_multiplier;
3827 initial_damage += dam.res_pen;
3828 }
3829 if( initial_damage < 0 ) {
3830 return;
3831 }
3832
3833 float dam = initial_damage;
3834
3835 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3836 sounds::sound( p, 30, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment",
3837 "alarm" );
3838 const tripoint abs = ms_to_sm_copy( getabs( p ) );
3839 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0, abs );
3840 }
3841
3842 const bool inc = proj.has_effect( ammo_effect_INCENDIARY ) ||
3843 proj.impact.type_damage( DT_HEAT ) > 0;
3844 if( const optional_vpart_position vp = veh_at( p ) ) {
3845 dam = vp->vehicle().damage( vp->part_index(), dam, inc ? DT_HEAT : DT_STAB, hit_items );
3846 }
3847
3848 ter_id terrain = ter( p );
3849 ter_t ter = terrain.obj();
3850
3851 if( ter.bash.ranged ) {
3852 const ranged_bash_info &ri = *ter.bash.ranged;
3853 if( !hit_items && !check( ri.block_unaimed_chance ) ) {
3854 // Nothing, it's a miss
3855 } else if( ri.reduction_laser && proj.has_effect( ammo_effect_LASER ) ) {
3856 dam -= rng( ri.reduction_laser->min, ri.reduction_laser->max );
3857 } else {
3858 dam -= rng( ri.reduction.min, ri.reduction.max );
3859 if( dam > ri.destroy_threshold ) {
3860 bash_params params{0, false, true, hit_items, 1.0, false};
3861 bash_ter_success( p, params );
3862 }
3863 if( dam <= 0 && is_transparent( p ) && get_avatar().sees( p ) ) {
3864 add_msg( _( "The shot is stopped by the %s!" ), tername( p ) );
3865 }
3866 if( ri.flammable && inc ) {
3867 add_field( p, fd_fire, 1 );
3868 }
3869 }
3870 } else if( impassable( p ) && !is_transparent( p ) ) {
3871 bash( p, dam, false );
3872 // TODO: Preserve some residual damage when it makes sense.
3873 dam = 0;
3874 }
3875
3876 for( const ammo_effect_str_id &ae_id : proj.get_ammo_effects() ) {
3877 const ammo_effect &ae = *ae_id;
3878 if( ae.trail_field_type ) {
3879 if( x_in_y( ae.trail_chance, 100 ) ) {
3881 }
3882 }
3883 }
3884
3885 dam = std::max( 0.0f, dam );
3886
3887 // Check fields?
3888 const field_entry *fieldhit = get_field( p, fd_web );
3889 if( fieldhit != nullptr ) {
3890 if( inc ) {
3891 add_field( p, fd_fire, fieldhit->get_field_intensity() - 1 );
3892 } else if( dam > 5 + fieldhit->get_field_intensity() * 5 &&
3893 one_in( 5 - fieldhit->get_field_intensity() ) ) {
3894 dam -= rng( 1, 2 + fieldhit->get_field_intensity() * 2 );
3895 remove_field( p, fd_web );
3896 }
3897 }
3898
3899 // Rescale the damage
3900 if( dam <= 0 ) {
3901 proj.impact.damage_units.clear();
3902 return;
3903 } else if( dam < initial_damage ) {
3904 proj.impact.mult_damage( dam / static_cast<double>( initial_damage ) );
3905 }
3906
3907 //Projectiles with NO_ITEM_DAMAGE flag won't damage items at all
3908 if( !hit_items || !inbounds( p ) ) {
3909 return;
3910 }
3911
3912 // Make sure the message is sensible for the ammo effects. Lasers aren't projectiles.
3913 std::string damage_message;
3914 if( proj.has_effect( ammo_effect_LASER ) ) {
3915 damage_message = _( "laser beam" );
3916 } else if( proj.has_effect( ammo_effect_LIGHTNING ) ) {
3917 damage_message = _( "bolt of electricity" );
3918 } else if( proj.has_effect( ammo_effect_PLASMA ) ) {
3919 damage_message = _( "bolt of plasma" );
3920 } else {
3921 damage_message = _( "flying projectile" );
3922 }
3923
3924 smash_trap( p, dam, damage_message );
3925 smash_items( p, dam, damage_message, false );
3926}
void smash_trap(const tripoint &p, const int power, const std::string &cause_message)
Tries to smash the trap at the given tripoint.
Definition: map.cpp:3054
@ DT_STAB
Definition: damage.h:27
static const ammo_effect_str_id ammo_effect_LIGHTNING("LIGHTNING")
static const ammo_effect_str_id ammo_effect_LASER("LASER")
static const ammo_effect_str_id ammo_effect_INCENDIARY("INCENDIARY")
static const ammo_effect_str_id ammo_effect_PLASMA("PLASMA")
int check(unformattable)
Definition: fmtlib_core.h:1610
int trail_chance
Definition: ammo_effect.h:45
int trail_intensity_max
Definition: ammo_effect.h:44
int trail_intensity_min
Definition: ammo_effect.h:43
field_type_id trail_field_type
Definition: ammo_effect.h:40
std::vector< damage_unit > damage_units
Definition: damage.h:52
float type_damage(damage_type dt) const
Definition: damage.cpp:64
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
float damage_multiplier
Definition: damage.h:40
float res_pen
Definition: damage.h:38
const std::set< ammo_effect_str_id > & get_ammo_effects()
Definition: projectile.h:42
damage_instance impact
Definition: projectile.h:21
bool has_effect(const ammo_effect_str_id &id) const
Definition: projectile.h:55
bool flammable
Definition: mapdata.h:41
numeric_interval< int > reduction
Definition: mapdata.h:37
int destroy_threshold
Definition: mapdata.h:40
std::optional< numeric_interval< int > > reduction_laser
Definition: mapdata.h:39
units::probability block_unaimed_chance
Definition: mapdata.h:42

References _, add_field(), add_msg(), sounds::alarm, ammo_effect_INCENDIARY, ammo_effect_LASER, ammo_effect_LIGHTNING, ammo_effect_PLASMA, damage_unit::amount, bash(), bash_ter_success(), ranged_bash_info::block_unaimed_chance, detail::check(), damage_unit::damage_multiplier, damage_instance::damage_units, ranged_bash_info::destroy_threshold, DT_HEAT, DT_STAB, fd_fire, fd_web, ranged_bash_info::flammable, g, projectile::get_ammo_effects(), get_avatar(), get_field(), field_entry::get_field_intensity(), getabs(), projectile::has_effect(), has_flag(), projectile::impact, impassable(), inbounds(), is_transparent(), ms_to_sm_copy(), damage_instance::mult_damage(), one_in(), ranged_bash_info::reduction, ranged_bash_info::reduction_laser, remove_field(), damage_unit::res_pen, rng(), sees(), smash_items(), smash_trap(), sounds::sound(), ter(), tername(), terrain, TIMED_EVENT_WANTED, ammo_effect::trail_chance, ammo_effect::trail_field_type, ammo_effect::trail_intensity_max, ammo_effect::trail_intensity_min, calendar::turn, damage_instance::type_damage(), veh_at(), and x_in_y().

◆ smash_items()

void map::smash_items ( const tripoint p,
int  power,
const std::string &  cause_message,
bool  do_destroy 
)

Tries to smash the items at the given tripoint.

Definition at line 3074 of file map.cpp.

3076{
3077 if( !has_items( p ) ) {
3078 return;
3079 }
3080
3081 // Keep track of how many items have been damaged, and what the first one is
3082 int items_damaged = 0;
3083 int items_destroyed = 0;
3084 std::string damaged_item_name;
3085
3086 // TODO: Bullets should be pretty much corpse-only
3087 constexpr const int min_destroy_threshold = 50;
3088
3089 std::vector<item> contents;
3090 map_stack items = i_at( p );
3091 for( auto it = items.begin(); it != items.end(); ) {
3092 if( it->has_flag( "EXPLOSION_SMASHED" ) ) {
3093 it++;
3094 continue;
3095 }
3096
3097 // detonate them if they can be exploded
3098 // We need to make a copy because the iterator validity is not predictable
3099 // see map_field.cpp process_fields_in_submap
3100 if( will_explode_on_impact( power ) && it->will_explode_in_fire() ) {
3101 item copy = *it;
3102 it = items.erase( it );
3103 if( copy.detonate( p, contents ) ) {
3104 // Need to restart, iterators may not be valid
3105 it = items.begin();
3106 }
3107 continue;
3108 }
3109
3110 // If the power is low or it's not an explosion, only pulp rezing corpses
3111 if( ( power < min_destroy_threshold || !do_destroy ) && !it->can_revive() ) {
3112 it++;
3113 continue;
3114 }
3115
3116 // Active explosives arbitrarily get double the destroy threshold
3117 bool is_active_explosive = it->active && it->type->get_use( "explosion" ) != nullptr;
3118 if( is_active_explosive && it->charges == 0 ) {
3119 it++;
3120 continue;
3121 }
3122
3123 const float material_factor = it->chip_resistance( true );
3124 // Intact non-rezing get a boost
3125 const float intact_mult = 2.0f -
3126 ( static_cast<float>( it->damage_level( it->max_damage() ) ) / it->max_damage() );
3127 const float destroy_threshold = min_destroy_threshold
3128 + material_factor * intact_mult;
3129 // For pulping, only consider material resistance. Non-rezing can only be destroyed.
3130 const float pulp_threshold = it->can_revive() ? material_factor : destroy_threshold;
3131 // Active explosives that will explode this turn are indestructible (they are exploding "now")
3132 if( power < pulp_threshold ) {
3133 it++;
3134 continue;
3135 }
3136
3137 bool item_was_destroyed = false;
3138 float destroy_chance = ( power - pulp_threshold ) / 4.0;
3139
3140 const bool by_charges = it->count_by_charges();
3141 if( by_charges ) {
3142 destroy_chance *= it->charges_per_volume( 250_ml );
3143 if( x_in_y( destroy_chance, destroy_threshold ) ) {
3144 item_was_destroyed = true;
3145 }
3146 } else {
3147 const field_type_id type_blood = it->is_corpse() ? it->get_mtype()->bloodType() : fd_null;
3148 float roll = rng_float( 0.0, destroy_chance );
3149 if( roll >= destroy_threshold ) {
3150 item_was_destroyed = true;
3151 } else if( roll >= pulp_threshold ) {
3152 // Only pulp
3153 it->set_damage( it->max_damage() );
3154 // TODO: Blood streak cone away from explosion
3155 add_splash( type_blood, p, 1, destroy_chance );
3156 // If it was the first item to be damaged, note it
3157 if( items_damaged == 0 ) {
3158 damaged_item_name = it->tname();
3159 }
3160 items_damaged++;
3161 }
3162 }
3163
3164 // Remove them if they were damaged too much
3165 if( item_was_destroyed ) {
3166 // But save the contents, except for irremovable gunmods
3167 for( item *elem : it->contents.all_items_top() ) {
3168 if( !elem->is_irremovable() ) {
3169 contents.push_back( item( *elem ) );
3170 }
3171 }
3172
3173 if( items_damaged == 0 ) {
3174 damaged_item_name = it->tname();
3175 }
3176 it = i_rem( p, it );
3177 items_damaged++;
3178 items_destroyed++;
3179 } else {
3180 it++;
3181 }
3182 }
3183
3184 // Let the player know that the item was damaged if they can see it.
3185 if( items_destroyed > 1 && g->u.sees( p ) ) {
3186 add_msg( m_bad, _( "The %s destroys several items!" ), cause_message );
3187 } else if( items_destroyed == 1 && items_damaged == 1 && g->u.sees( p ) ) {
3188 //~ %1$s: the cause of destruction, %2$s: destroyed item name
3189 add_msg( m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, damaged_item_name );
3190 } else if( items_damaged > 1 && g->u.sees( p ) ) {
3191 add_msg( m_bad, _( "The %s damages several items." ), cause_message );
3192 } else if( items_damaged == 1 && g->u.sees( p ) ) {
3193 //~ %1$s: the cause of damage, %2$s: damaged item name
3194 add_msg( m_bad, _( "The %1$s damages the %2$s." ), cause_message, damaged_item_name );
3195 }
3196
3197 for( const item &it : contents ) {
3198 add_item_or_charges( p, it );
3199 }
3200}
void add_splash(const field_type_id &type, const tripoint &center, int radius, int intensity)
Definition: map.cpp:5668
static bool will_explode_on_impact(const int power)
Definition: map.cpp:3046

References _, add_item_or_charges(), add_msg(), add_splash(), item_contents::all_items_top(), item_stack::begin(), item::contents, item::detonate(), item_stack::end(), map_stack::erase(), fd_null, g, has_items(), i_at(), i_rem(), m_bad, rng_float(), will_explode_on_impact(), and x_in_y().

Referenced by move_vehicle(), and shoot().

◆ smash_trap()

void map::smash_trap ( const tripoint p,
const int  power,
const std::string &  cause_message 
)

Tries to smash the trap at the given tripoint.

Definition at line 3054 of file map.cpp.

3055{
3056 const trap &tr = get_map().tr_at( p );
3057 if( tr.is_null() ) {
3058 return;
3059 }
3060
3061 const bool is_explosive_trap = !tr.is_benign() && tr.vehicle_data.do_explosion;
3062
3063 if( !will_explode_on_impact( power ) || !is_explosive_trap ) {
3064 return;
3065 }
3066 // make a fake NPC to trigger the trap
3067 npc dummy;
3068 dummy.set_fake( true );
3069 dummy.name = cause_message;
3070 dummy.setpos( p );
3071 tr.trigger( p, &dummy );
3072}
virtual void set_fake(bool fake_value)
Sets a Creature's fake boolean.
Definition: creature.cpp:1003
vehicle_handle_trap_data vehicle_data
Definition: trap.h:122
bool is_benign() const
If true, this is not really a trap and there won't be any safety queries before stepping onto it (e....
Definition: trap.h:159

References vehicle_handle_trap_data::do_explosion, get_map(), trap::is_benign(), trap::is_null(), Character::name, Creature::set_fake(), npc::setpos(), tr_at(), trap::trigger(), trap::vehicle_data, and will_explode_on_impact().

Referenced by shoot().

◆ spawn_an_item() [1/2]

item & map::spawn_an_item ( const tripoint p,
item  new_item,
int  charges,
int  damlevel 
)

Definition at line 4265 of file map.cpp.

4267{
4268 if( charges && new_item.charges > 0 ) {
4269 //let's fail silently if we specify charges for an item that doesn't support it
4270 new_item.charges = charges;
4271 }
4272 new_item = new_item.in_its_container();
4273 if( ( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) ||
4274 has_flag( "DESTROY_ITEM", p ) ) {
4275 return null_item_reference();
4276 }
4277
4278 new_item.set_damage( damlevel );
4279
4280 return add_item_or_charges( p, new_item );
4281}
item & set_damage(int qty)
Filter setting damage constrained by min_damage and max_damage.
Definition: item.cpp:718
item in_its_container() const
Returns this item into its default container.
Definition: item.cpp:845

References add_item_or_charges(), item::charges, has_flag(), item::in_its_container(), LIQUID, item::made_of(), null_item_reference(), and item::set_damage().

Referenced by spawn_an_item(), and spawn_item().

◆ spawn_an_item() [2/2]

void map::spawn_an_item ( point  p,
item  new_item,
int  charges,
int  damlevel 
)
inline

Definition at line 1252 of file map.h.

1252 {
1253 spawn_an_item( tripoint( p, abs_sub.z ), new_item, charges, damlevel );
1254 }
item & spawn_an_item(const tripoint &p, item new_item, int charges, int damlevel)
Definition: map.cpp:4265

References abs_sub, spawn_an_item(), and tripoint::z.

◆ spawn_artifact()

void map::spawn_artifact ( const tripoint p)

Definition at line 4304 of file map.cpp.

4305{
4307}
itype_id new_artifact()
Definition: artifact.cpp:677

References add_item_or_charges(), new_artifact(), and calendar::start_of_cataclysm.

Referenced by draw_mine(), and draw_temple().

◆ spawn_item() [1/4]

void map::spawn_item ( const tripoint p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)

Definition at line 4314 of file map.cpp.

4317{
4318 if( type_id.is_null() ) {
4319 return;
4320 }
4321
4322 if( item_is_blacklisted( type_id ) ) {
4323 return;
4324 }
4325 // recurse to spawn (quantity - 1) items
4326 for( size_t i = 1; i < quantity; i++ ) {
4327 spawn_item( p, type_id, 1, charges, birthday, damlevel );
4328 }
4329 // spawn the item
4330 item new_item( type_id, birthday );
4331 if( one_in( 3 ) && new_item.has_flag( "VARSIZE" ) ) {
4332 new_item.set_flag( "FIT" );
4333 }
4334
4335 spawn_an_item( p, new_item, charges, damlevel );
4336}
bool is_null() const
Returns whether this represents the id of the null-object (in which case it's the null-id).
Definition: string_id.h:325
bool item_is_blacklisted(const itype_id &id)

References item::has_flag(), string_id< T >::is_null(), item_is_blacklisted(), one_in(), item::set_flag(), spawn_an_item(), and spawn_item().

Referenced by jmapgen_spawn_item::apply(), MapExtras::burned_ground_parser(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_burnproducts(), MapExtras::dead_vegetation_parser(), game::disable_robot(), draw_lab(), draw_mine(), draw_office_tower(), mapgen_cavern(), mapgen_tutorial(), MapExtras::mx_casings(), MapExtras::mx_drugdeal(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_roadworks(), om_cutdown_trees(), trap::on_disarmed(), mission_start::place_deposit_box(), MapExtras::place_fumarole(), mission_start::place_priest_diary(), place_vending(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), spawn_item(), and game::vertical_move().

◆ spawn_item() [2/4]

void map::spawn_item ( const tripoint p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1213 of file map.h.

1215 {
1216 spawn_item( p, itype_id( type_id ), quantity, charges, birthday, damlevel );
1217 }

References itype_id, and spawn_item().

◆ spawn_item() [3/4]

void map::spawn_item ( point  p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1205 of file map.h.

1207 {
1208 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1209 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [4/4]

void map::spawn_item ( point  p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1218 of file map.h.

1220 {
1221 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1222 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_items() [1/2]

std::vector< item * > map::spawn_items ( const tripoint p,
const std::vector< item > &  new_items 
)

Definition at line 4283 of file map.cpp.

4284{
4285 std::vector<item *> ret;
4286 if( !inbounds( p ) || has_flag( "DESTROY_ITEM", p ) ) {
4287 return ret;
4288 }
4289 const bool swimmable = has_flag( "SWIMMABLE", p );
4290 for( const item &new_item : new_items ) {
4291
4292 if( new_item.made_of( LIQUID ) && swimmable ) {
4293 continue;
4294 }
4295 item &it = add_item_or_charges( p, new_item );
4296 if( !it.is_null() ) {
4297 ret.push_back( &it );
4298 }
4299 }
4300
4301 return ret;
4302}
bool is_null() const
Definition: item.cpp:736

References add_item_or_charges(), has_flag(), inbounds(), item::is_null(), LIQUID, and cata::hash64_detail::ret.

Referenced by jmapgen_loot::apply(), bash_furn_success(), bash_items(), bash_ter_success(), talk_function::loot_building(), MapExtras::mx_casings(), MapExtras::mx_corpses(), process_fields_in_submap(), put_items_from_loc(), veh_utils::repair_part(), and spawn_items().

◆ spawn_items() [2/2]

void map::spawn_items ( point  p,
const std::vector< item > &  new_items 
)
inline

Definition at line 1328 of file map.h.

1328 {
1329 spawn_items( tripoint( p, abs_sub.z ), new_items );
1330 }

References abs_sub, spawn_items(), and tripoint::z.

◆ spawn_monsters()

void map::spawn_monsters ( bool  ignore_sight)

Spawn monsters from submap spawn points and from the overmap.

Parameters
ignore_sightIf true, monsters may spawn in the view of the player character (useful when the whole map has been loaded instead, e.g. when starting a new game, or after teleportation or after moving vertically). If false, monsters are not spawned in view of player character.

Definition at line 7847 of file map.cpp.

7848{
7849 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
7850 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
7851 tripoint gp;
7852 int &gx = gp.x;
7853 int &gy = gp.y;
7854 int &gz = gp.z;
7855 for( gz = zmin; gz <= zmax; gz++ ) {
7856 for( gx = 0; gx < my_MAPSIZE; gx++ ) {
7857 for( gy = 0; gy < my_MAPSIZE; gy++ ) {
7858 spawn_monsters_submap( gp, ignore_sight );
7859 }
7860 }
7861 }
7862}
void spawn_monsters_submap(const tripoint &gp, bool ignore_sight)
Definition: map.cpp:7792

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, spawn_monsters_submap(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn(), game::place_player_overmap(), game::start_game(), game::update_map(), and game::vertical_shift().

◆ spawn_monsters_submap()

void map::spawn_monsters_submap ( const tripoint gp,
bool  ignore_sight 
)
private

Definition at line 7792 of file map.cpp.

7793{
7794 // Load unloaded monsters
7795 // TODO: fix point types
7797
7798 // Only spawn new monsters after existing monsters are loaded.
7799 // TODO: fix point types
7800 auto groups = overmap_buffer.groups_at( tripoint_abs_sm( gp + abs_sub.xy() ) );
7801 for( auto &mgp : groups ) {
7802 spawn_monsters_submap_group( gp, *mgp, ignore_sight );
7803 }
7804
7805 submap *const current_submap = get_submap_at_grid( gp );
7806 const tripoint gp_ms = sm_to_ms_copy( gp );
7807
7808 for( auto &i : current_submap->spawns ) {
7809 const tripoint center = gp_ms + i.pos;
7811
7812 for( int j = 0; j < i.count; j++ ) {
7813 monster tmp( i.type );
7814 tmp.mission_id = i.mission_id;
7815 if( i.name != "NONE" ) {
7816 tmp.unique_name = i.name;
7817 }
7818 if( i.friendly ) {
7819 tmp.friendly = -1;
7820 }
7821
7822 const auto valid_location = [&]( const tripoint & p ) {
7823 // Checking for creatures via g is only meaningful if this is the main game map.
7824 // If it's some local map instance, the coordinates will most likely not even match.
7825 return ( !g || &get_map() != this || !g->critter_at( p ) ) && tmp.can_move_to( p );
7826 };
7827
7828 const auto place_it = [&]( const tripoint & p ) {
7829 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7830 if( placed ) {
7831 placed->on_load();
7832 }
7833 };
7834
7835 // First check out defined spawn location for a valid placement, and if that doesn't work
7836 // then fall back to picking a random point that is a valid location.
7837 if( valid_location( center ) ) {
7838 place_it( center );
7839 } else if( const std::optional<tripoint> pos = random_point( points, valid_location ) ) {
7840 place_it( *pos );
7841 }
7842 }
7843 }
7844 current_submap->spawns.clear();
7845}
void spawn_monsters_submap_group(const tripoint &gp, mongroup &group, bool ignore_sight)
Definition: map.cpp:7658
void on_load()
Retroactively update monster.
Definition: monster.cpp:3056
std::vector< mongroup * > groups_at(const tripoint_abs_sm &p)
Monster groups at p - absolute submap coordinates.
void spawn_monster(const tripoint_abs_sm &p)
Spawn monsters from the overmap onto the main map (game::m).

References abs_sub, monster::can_move_to(), center, monster::friendly, g, get_map(), get_submap_at_grid(), overmapbuffer::groups_at(), monster::mission_id, monster::on_load(), overmap_buffer, points_in_radius(), random_point(), sm_to_ms_copy(), overmapbuffer::spawn_monster(), spawn_monsters_submap_group(), submap::spawns, monster::unique_name, and tripoint::xy().

Referenced by spawn_monsters().

◆ spawn_monsters_submap_group()

void map::spawn_monsters_submap_group ( const tripoint gp,
mongroup group,
bool  ignore_sight 
)
private

Definition at line 7658 of file map.cpp.

7659{
7660 const int s_range = std::min( HALF_MAPSIZE_X,
7661 g->u.sight_range( g->light_level( g->u.posz() ) ) );
7662 int pop = group.population;
7663 std::vector<tripoint> locations;
7664 if( !ignore_sight ) {
7665 // If the submap is one of the outermost submaps, assume that monsters are
7666 // invisible there.
7667 if( gp.x == 0 || gp.y == 0 || gp.x + 1 == MAPSIZE || gp.y + 1 == MAPSIZE ) {
7668 ignore_sight = true;
7669 }
7670 }
7671
7672 if( gp.z != g->u.posz() ) {
7673 // Note: this is only OK because 3D vision isn't a thing yet
7674 ignore_sight = true;
7675 }
7676
7677 static const auto allow_on_terrain = [&]( const tripoint & p ) {
7678 // TODO: flying creatures should be allowed to spawn without a floor,
7679 // but the new creature is created *after* determining the terrain, so
7680 // we can't check for it here.
7681 return passable( p ) && has_floor( p );
7682 };
7683
7684 // If the submap is uniform, we can skip many checks
7685 const submap *current_submap = get_submap_at_grid( gp );
7686 bool ignore_terrain_checks = false;
7687 bool ignore_inside_checks = gp.z < 0;
7688 if( current_submap->is_uniform ) {
7689 const tripoint upper_left{ SEEX * gp.x, SEEY * gp.y, gp.z };
7690 if( !allow_on_terrain( upper_left ) ||
7691 ( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, upper_left ) ) ) {
7692 const tripoint glp = getabs( gp );
7693 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7694 << " at uniform submap " << gp << " global " << glp;
7695 return;
7696 }
7697
7698 ignore_terrain_checks = true;
7699 ignore_inside_checks = true;
7700 }
7701
7702 for( int x = 0; x < SEEX; ++x ) {
7703 for( int y = 0; y < SEEY; ++y ) {
7704 int fx = x + SEEX * gp.x;
7705 int fy = y + SEEY * gp.y;
7706 tripoint fp{ fx, fy, gp.z };
7707 if( g->critter_at( fp ) != nullptr ) {
7708 continue; // there is already some creature
7709 }
7710
7711 if( !ignore_terrain_checks && !allow_on_terrain( fp ) ) {
7712 continue; // solid area, impassable
7713 }
7714
7715 if( !ignore_sight && sees( g->u.pos(), fp, s_range ) ) {
7716 continue; // monster must spawn outside the viewing range of the player
7717 }
7718
7719 if( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, fp ) ) {
7720 continue; // monster must spawn outside.
7721 }
7722
7723 locations.push_back( fp );
7724 }
7725 }
7726
7727 if( locations.empty() ) {
7728 // TODO: what now? there is no possible place to spawn monsters, most
7729 // likely because the player can see all the places.
7730 const tripoint glp = getabs( gp );
7731 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7732 << " at " << gp << " global " << glp;
7733 // Just kill the group. It's not like we're removing existing monsters
7734 // Unless it's a horde - then don't kill it and let it spawn behind a tree or smoke cloud
7735 if( !group.horde ) {
7736 group.clear();
7737 }
7738
7739 return;
7740 }
7741
7742 if( pop ) {
7743 // Populate the group from its population variable.
7744 for( int m = 0; m < pop; m++ ) {
7746 if( !spawn_details.name ) {
7747 continue;
7748 }
7749 monster tmp( spawn_details.name );
7750
7751 // If a monster came from a horde population, configure them to always be willing to rejoin a horde.
7752 if( group.horde ) {
7753 tmp.set_horde_attraction( MHA_ALWAYS );
7754 }
7755 for( int i = 0; i < spawn_details.pack_size; i++ ) {
7756 group.monsters.push_back( tmp );
7757 }
7758 }
7759 }
7760
7761 // Find horde's target submap
7762 // TODO: fix point types
7763 tripoint horde_target( tripoint( -abs_sub.xy(), abs_sub.z ) + group.target.xy().raw() );
7764 sm_to_ms( horde_target );
7765 for( auto &tmp : group.monsters ) {
7766 for( int tries = 0; tries < 10 && !locations.empty(); tries++ ) {
7768 if( !tmp.can_move_to( p ) ) {
7769 continue; // target can not contain the monster
7770 }
7771 if( group.horde ) {
7772 // Give monster a random point near horde's expected destination
7773 const tripoint rand_dest = horde_target +
7774 point( rng( 0, SEEX ), rng( 0, SEEY ) );
7775 const int turns = rl_dist( p, rand_dest ) + group.interest;
7776 tmp.wander_to( rand_dest, turns );
7777 add_msg( m_debug, "%s targeting %d,%d,%d", tmp.disp_name(),
7778 tmp.wander_pos.x, tmp.wander_pos.y, tmp.wander_pos.z );
7779 }
7780
7781 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7782 if( placed ) {
7783 placed->on_load();
7784 }
7785 break;
7786 }
7787 }
7788 // indicates the group is empty, and can be removed later
7789 group.clear();
7790}
void sm_to_ms(int &x, int &y)
static constexpr int HALF_MAPSIZE_X
@ MHA_ALWAYS
Definition: monster.h:76
generic_factory< overmap_location > locations("overmap location")

References abs_sub, add_msg(), dbg, g, get_submap_at_grid(), getabs(), MonsterGroupManager::GetResultFromGroup(), HALF_MAPSIZE_X, has_flag_ter_or_furn(), has_floor(), submap::is_uniform, anonymous_namespace{overmap_location.cpp}::locations, m_debug, MAPSIZE, MHA_ALWAYS, MonsterGroupResult::name, monster::on_load(), MonsterGroupResult::pack_size, passable(), random_entry_removed(), rl_dist(), rng(), sees(), SEEX, SEEY, monster::set_horde_attraction(), sm_to_ms(), TFLAG_INDOORS, Warn, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by spawn_monsters_submap().

◆ spawn_natural_artifact()

void map::spawn_natural_artifact ( const tripoint p,
artifact_natural_property  prop 
)

Definition at line 4309 of file map.cpp.

4310{
4312}
itype_id new_natural_artifact(artifact_natural_property prop)
Definition: artifact.cpp:931

References add_item_or_charges(), new_natural_artifact(), and calendar::start_of_cataclysm.

Referenced by debug_menu::debug(), and MapExtras::mx_portal_in().

◆ spread_gas()

void map::spread_gas ( field_entry cur,
const tripoint p,
int  percent_spread,
const time_duration outdoor_age_speedup,
scent_block sblk 
)
private

Definition at line 252 of file map_field.cpp.

254{
255 map &here = get_map();
256 // TODO: fix point types
257 const oter_id &cur_om_ter =
259 const bool sheltered = g->is_sheltered( p );
261 const int winddirection = weather.winddirection;
262 const int windpower = get_local_windpower( weather.windspeed, cur_om_ter, p, winddirection,
263 sheltered );
264
265 const int current_intensity = cur.get_field_intensity();
266 const field_type_id ft_id = cur.get_field_type();
267
268 const int scent_neutralize = ft_id->get_intensity_level( current_intensity -
270
271 if( scent_neutralize > 0 ) {
272 // modify scents by neutralization value (minus)
273 for( const tripoint &tmp : points_in_radius( p, 1 ) ) {
274 sblk.apply_gas( tmp, scent_neutralize );
275 }
276 }
277
278 // Dissipate faster outdoors.
279 if( is_outside( p ) ) {
280 const time_duration current_age = cur.get_field_age();
281 cur.set_field_age( current_age + outdoor_age_speedup );
282 }
283
284 // Bail out if we don't meet the spread chance or required intensity.
285 if( current_intensity <= 1 || rng( 1, 100 - windpower ) > percent_spread ) {
286 return;
287 }
288
289 // First check if we can fall
290 // TODO: Make fall and rise chances parameters to enable heavy/light gas
291 if( zlevels && p.z > -OVERMAP_DEPTH ) {
292 const tripoint down{ p.xy(), p.z - 1 };
293 if( gas_can_spread_to( cur, p, down ) && valid_move( p, down, true, true ) ) {
294 maptile down_tile = maptile_at_internal( down );
295 gas_spread_to( cur, down_tile, down );
296 return;
297 }
298 }
299
300 auto neighs = get_neighbors( p );
301 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
302 std::vector<size_t> spread;
303 std::vector<size_t> neighbour_vec;
304 // Then, spread to a nearby point.
305 // If not possible (or randomly), try to spread up
306 // Wind direction will block the field spreading into the wind.
307 // Start at end_it + 1, then wrap around until all elements have been processed.
308 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
309 count != neighs.size();
310 i = ( i + 1 ) % neighs.size(), count++ ) {
311 const auto &neigh = neighs[i];
312 if( gas_can_spread_to( cur, p, neigh.first ) ) {
313 spread.push_back( i );
314 }
315 }
316 auto maptiles = get_wind_blockers( winddirection, p );
317 // Three map tiles that are facing the wind direction.
318 const maptile remove_tile = std::get<0>( maptiles );
319 const maptile remove_tile2 = std::get<1>( maptiles );
320 const maptile remove_tile3 = std::get<2>( maptiles );
321 if( !spread.empty() && ( !zlevels || one_in( spread.size() ) ) ) {
322 // Construct the destination from offset and p
323 if( g->is_sheltered( p ) || windpower < 5 ) {
324 std::pair<tripoint, maptile> &n = neighs[ random_entry( spread ) ];
325 gas_spread_to( cur, n.second, n.first );
326 } else {
327 end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
328 // Start at end_it + 1, then wrap around until all elements have been processed.
329 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
330 count != neighs.size();
331 i = ( i + 1 ) % neighs.size(), count++ ) {
332 const auto &neigh = neighs[i].second;
333 if( ( neigh.pos_.x != remove_tile.pos_.x && neigh.pos_.y != remove_tile.pos_.y ) ||
334 ( neigh.pos_.x != remove_tile2.pos_.x && neigh.pos_.y != remove_tile2.pos_.y ) ||
335 ( neigh.pos_.x != remove_tile3.pos_.x && neigh.pos_.y != remove_tile3.pos_.y ) ) {
336 neighbour_vec.push_back( i );
337 } else if( x_in_y( 1, std::max( 2, windpower ) ) ) {
338 neighbour_vec.push_back( i );
339 }
340 }
341 if( !neighbour_vec.empty() ) {
342 std::pair<tripoint, maptile> &n = neighs[neighbour_vec[rng( 0, neighbour_vec.size() - 1 )]];
343 gas_spread_to( cur, n.second, n.first );
344 }
345 }
346 } else if( zlevels && p.z < OVERMAP_HEIGHT ) {
347 const tripoint up{ p.xy(), p.z + 1 };
348 if( gas_can_spread_to( cur, p, up ) && valid_move( p, up, true, true ) ) {
349 maptile up_tile = maptile_at_internal( up );
350 gas_spread_to( cur, up_tile, up );
351 }
352 }
353}
std::tuple< maptile, maptile, maptile > get_wind_blockers(const int &winddirection, const tripoint &pos)
Definition: map_field.cpp:1894
bool gas_can_spread_to(field_entry &cur, const tripoint &src, const tripoint &dst)
Definition: map_field.cpp:212
void gas_spread_to(field_entry &cur, maptile &dst, const tripoint &p)
Definition: map_field.cpp:226
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:938
const field_intensity_level & get_intensity_level(int level=0) const
Definition: field_type.cpp:130
point pos_
Definition: submap.h:243
void apply_gas(const tripoint &p, const int nintensity=0)
Definition: scent_block.cpp:45

References scent_block::apply_gas(), detail::count(), g, gas_can_spread_to(), gas_spread_to(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_type::get_intensity_level(), get_local_windpower(), get_map(), get_neighbors(), get_weather(), get_wind_blockers(), anonymous_namespace{iexamine_elevator.cpp}::elevator::here(), is_outside(), maptile_at_internal(), ms_to_omt_copy(), one_in(), overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), maptile::pos_, random_entry(), rng(), field_intensity_level::scent_neutralization, field_entry::set_field_age(), overmapbuffer::ter(), valid_move(), point::x, x_in_y(), tripoint::xy(), point::y, tripoint::z, and zlevels.

Referenced by process_fields_in_submap().

◆ stored_volume()

units::volume map::stored_volume ( const tripoint p)

Definition at line 4344 of file map.cpp.

4345{
4346 return i_at( p ).stored_volume();
4347}
units::volume stored_volume() const
Total volume of the items here.
Definition: item_stack.cpp:98

References i_at(), and item_stack::stored_volume().

◆ support_dirty()

void map::support_dirty ( const tripoint p)
private

Definition at line 2349 of file map.cpp.

2350{
2351 if( zlevels ) {
2352 support_cache_dirty.insert( p );
2353 }
2354}

References support_cache_dirty, and zlevels.

Referenced by add_field(), add_item_or_charges(), drop_furniture(), furn_set(), ter_set(), and update_suspension_cache().

◆ supports_above()

bool map::supports_above ( const tripoint p) const

Does this tile support vehicles and furniture above it.

Definition at line 2102 of file map.cpp.

2103{
2104 const maptile tile = maptile_at( p );
2105 const ter_t &ter = tile.get_ter_t();
2106 if( ter.movecost == 0 ) {
2107 return true;
2108 }
2109
2110 const furn_id frn_id = tile.get_furn();
2111 if( frn_id != f_null ) {
2112 const furn_t &frn = frn_id.obj();
2113 if( frn.movecost < 0 ) {
2114 return true;
2115 }
2116 }
2117
2118 return veh_at( p ).has_value();
2119}
furn_id get_furn() const
Definition: submap.h:256

References f_null, maptile::get_furn(), maptile::get_ter_t(), maptile_at(), map_data_common_t::movecost, int_id< T >::obj(), ter(), and veh_at().

Referenced by drop_furniture().

◆ ter() [1/2]

ter_id map::ter ( const tripoint p) const

Definition at line 1563 of file map.cpp.

1564{
1565 if( !inbounds( p ) ) {
1566 return t_null;
1567 }
1568
1569 point l;
1570 submap *const current_submap = get_submap_at( p, l );
1571
1572 return current_submap->get_ter( l );
1573}

References get_submap_at(), submap::get_ter(), inbounds(), and t_null.

Referenced by actualize(), ter_furn_transform::add_all_messages(), add_boardable(), cata_event_dispatch::avatar_moves(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), close_door(), coverage(), MapExtras::dead_vegetation_parser(), determine_wall_corner(), displace_water(), construct::done_digormine_stair(), construct::done_mine_upstair(), draw_connections(), draw_lab(), editmap::draw_main_ui_overlay(), draw_mine(), draw_temple(), draw_triffid(), examine(), game::examine(), game::extended_description(), feature< ter_id >(), talk_function::field_plant(), game::find_or_make_stairs(), find_potential_computer_point(), gas_can_spread_to(), get_changed_ids_from_update(), get_harvest(), get_harvest_names(), get_known_connections(), get_roof(), get_ter_transforms_into(), has_flag_ter(), hit_with_acid(), advanced_inv_area::init(), is_bashable(), is_bashable_ter(), anonymous_namespace{gates.cpp}::gate_data::is_suitable_wall(), is_suspension_valid(), talk_function::loot_building(), mapgen_ants_generic(), mapgen_lake_shore(), fungal_effects::marlossify(), map_stack::max_volume(), map_funcs::migo_nerve_cage_removal(), avatar_action::move(), move_cost(), move_vehicle(), MapExtras::mx_crater(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_portal_in(), MapExtras::mx_shrubbery(), obstacle_coverage(), om_cutdown_trees(), om_harvest_ter(), open_door(), mission_start::place_deposit_box(), place_items(), game::place_player(), game::print_fields_info(), game::print_graffiti_info(), process_fields_in_submap(), produce_sap(), rad_scorch(), resolve_regional_terrain_and_furniture(), restock_fruits(), mission_start::reveal_lab_train_depot(), shoot(), supports_above(), temperature_flag_at_point(), rot::temperature_flag_for_location(), ter(), tername(), ter_furn_transform::transform(), translate(), translate_radius(), trap_set(), Character::update_bodytemp(), update_suspension_cache(), vehicle_wheel_traction(), game::vertical_move(), game::walk_move(), and water_from().

◆ ter() [2/2]

ter_id map::ter ( point  p) const
inline

Definition at line 816 of file map.h.

816 {
817 return ter( tripoint( p, abs_sub.z ) );
818 }

References abs_sub, ter(), and tripoint::z.

◆ ter_set() [1/2]

bool map::ter_set ( const tripoint p,
const ter_id new_terrain 
)

Definition at line 1704 of file map.cpp.

1705{
1706 if( !inbounds( p ) ) {
1707 return false;
1708 }
1709
1710 point l;
1711 submap *const current_submap = get_submap_at( p, l );
1712 const ter_id old_id = current_submap->get_ter( l );
1713 if( old_id == new_terrain ) {
1714 // Nothing changed
1715 return false;
1716 }
1717
1718 current_submap->set_ter( l, new_terrain );
1719
1720 // Set the dirty flags
1721 const ter_t &old_t = old_id.obj();
1722 const ter_t &new_t = new_terrain.obj();
1723
1724 // HACK: Hack around ledges in traplocs or else it gets NASTY in z-level mode
1725 if( old_t.trap != tr_null && old_t.trap != tr_ledge ) {
1726 auto &traps = traplocs[old_t.trap.to_i()];
1727 const auto iter = std::find( traps.begin(), traps.end(), p );
1728 if( iter != traps.end() ) {
1729 traps.erase( iter );
1730 }
1731 }
1732 if( new_t.trap != tr_null && new_t.trap != tr_ledge ) {
1733 traplocs[new_t.trap.to_i()].push_back( p );
1734 }
1735
1736 if( old_t.transparent != new_t.transparent ) {
1739 }
1740
1741 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1743 }
1744
1745 if( new_t.has_flag( TFLAG_NO_FLOOR ) != old_t.has_flag( TFLAG_NO_FLOOR ) ) {
1747 // It's a set, not a flag
1748 support_cache_dirty.insert( p );
1750 }
1751
1752 if( new_t.has_flag( TFLAG_SUSPENDED ) != old_t.has_flag( TFLAG_SUSPENDED ) ) {
1754 if( new_t.has_flag( TFLAG_SUSPENDED ) ) {
1755 level_cache &ch = get_cache( p.z );
1756 ch.suspension_cache.emplace_back( getabs( p ).xy() );
1757 }
1758 }
1759
1761
1763
1764 // TODO: Limit to changes that affect move cost, traps and stairs
1766
1767 tripoint above( p.xy(), p.z + 1 );
1768 // Make sure that if we supported something and no longer do so, it falls down
1769 support_dirty( above );
1770
1771 return true;
1772}
std::list< point > suspension_cache
Definition: map.h:312
trap_id trap
Definition: mapdata.h:475

References detail::find(), get_cache(), get_submap_at(), submap::get_ter(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), int_id< T >::obj(), set_floor_cache_dirty(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), submap::set_ter(), set_transparency_cache_dirty(), support_cache_dirty, support_dirty(), level_cache::suspension_cache, TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUSPENDED, int_id< T >::to_i(), tr_ledge, tr_null, map_data_common_t::transparent, ter_t::trap, traplocs, tripoint::xy(), and tripoint::z.

Referenced by add_computer(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_setmap::apply(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), iexamine::cardreader_robofac(), close_door(), collapse_at(), collapse_invalid_suspension(), MapExtras::dead_vegetation_parser(), displace_water(), construct::done_digormine_stair(), construct::done_mine_upstair(), construct::done_ramp_high(), construct::done_ramp_low(), construct::done_wood_stairs(), draw_anthill(), draw_circle_ter(), draw_connections(), draw_lab(), draw_line_ter(), draw_mine(), draw_rough_circle_ter(), draw_slimepit(), draw_square_ter(), draw_temple(), draw_triffid(), farm_action(), talk_function::field_harvest(), game::forced_door_closing(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), hit_with_acid(), talk_function::loot_building(), make_rubble(), mapgen_ants_curved(), mapgen_ants_four_way(), mapgen_ants_generic(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_hellmouth(), mapgen_highway(), mapgen_hive(), mapgen_lake_shore(), mapgen_null(), mapgen_parking_lot(), mapgen_rift(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rock_partial(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_test(), mapgen_tutorial(), fungal_effects::marlossify(), map_funcs::migo_nerve_cage_removal(), move_vehicle(), MapExtras::mx_bandits_block(), MapExtras::mx_clay_deposit(), MapExtras::mx_clearcut(), MapExtras::mx_crater(), MapExtras::mx_grave(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_wasp(), MapExtras::mx_pond(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_shrubbery(), MapExtras::mx_spider(), om_cutdown_trees(), om_harvest_ter(), om_set_hide_site(), open_door(), MapExtras::place_fumarole(), place_gas_pump(), mission_start::place_npc_software(), process_fields_in_submap(), rad_scorch(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), restock_fruits(), science_room(), set(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_set(), ter_furn_transform::transform(), translate(), translate_radius(), and game::vertical_move().

◆ ter_set() [2/2]

bool map::ter_set ( point  p,
const ter_id new_terrain 
)
inline

Definition at line 841 of file map.h.

841 {
842 return ter_set( tripoint( p, abs_sub.z ), new_terrain );
843 }

References abs_sub, ter_set(), and tripoint::z.

◆ tername() [1/2]

std::string map::tername ( const tripoint p) const

◆ tername() [2/2]

std::string map::tername ( point  p) const
inline

Definition at line 846 of file map.h.

846 {
847 return tername( tripoint( p, abs_sub.z ) );
848 }

References abs_sub, tername(), and tripoint::z.

◆ tinder_at()

bool map::tinder_at ( const tripoint p)

Checks if there are any tinder flagged items on the tile.

Parameters
ptile to check

Definition at line 2678 of file map.cpp.

2679{
2680 for( const auto &i : i_at( p ) ) {
2681 if( i.has_flag( "TINDER" ) ) {
2682 return true;
2683 }
2684 }
2685 return false;
2686}

References i_at().

◆ tr_at()

const trap & map::tr_at ( const tripoint p) const

◆ translate()

void map::translate ( const ter_id from,
const ter_id to 
)

Definition at line 4053 of file map.cpp.

4054{
4055 if( from == to ) {
4056 debugmsg( "map::translate %s => %s",
4057 from.obj().name(),
4058 from.obj().name() );
4059 return;
4060 }
4061 for( const tripoint &p : points_on_zlevel() ) {
4062 if( ter( p ) == from ) {
4063 ter_set( p, to );
4064 }
4065 }
4066}

References debugmsg, map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), and ter_set().

Referenced by jmapgen_translate::apply(), mapgen_lake_shore(), start_location::prepare_map(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and mission_start::ranch_scavenger_3().

◆ translate_radius()

void map::translate_radius ( const ter_id from,
const ter_id to,
float  radi,
const tripoint p,
bool  same_submap = false,
bool  toggle_between = false 
)

Definition at line 4069 of file map.cpp.

4071{
4072 if( from == to ) {
4073 debugmsg( "map::translate %s => %s", from.obj().name(), to.obj().name() );
4074 return;
4075 }
4076
4077 const tripoint abs_omt_p = ms_to_omt_copy( getabs( p ) );
4078 for( const tripoint &t : points_on_zlevel() ) {
4079 const tripoint abs_omt_t = ms_to_omt_copy( getabs( t ) );
4080 const float radiX = trig_dist( p, t );
4081 if( ter( t ) == from ) {
4082 // within distance, and either no submap limitation or same overmap coords.
4083 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
4084 ter_set( t, to );
4085 }
4086 } else if( toggle_between && ter( t ) == to ) {
4087 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
4088 ter_set( t, from );
4089 }
4090 }
4091 }
4092}

References debugmsg, getabs(), ms_to_omt_copy(), map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), ter_set(), and trig_dist().

Referenced by computer_session::action_lock(), computer_session::action_open(), computer_session::action_release(), computer_session::action_release_bionics(), computer_session::action_shutters(), and computer_session::action_unlock().

◆ trap_locations()

const std::vector< tripoint > & map::trap_locations ( const trap_id type) const

Definition at line 7893 of file map.cpp.

7894{
7895 return traplocs[type.to_i()];
7896}

References traplocs, and type.

◆ trap_set()

void map::trap_set ( const tripoint p,
const trap_id type 
)

Definition at line 5310 of file map.cpp.

5311{
5312 if( !inbounds( p ) ) {
5313 return;
5314 }
5315
5316 point l;
5317 submap *const current_submap = get_submap_at( p, l );
5318 const ter_t &ter = current_submap->get_ter( l ).obj();
5319 if( ter.trap != tr_null ) {
5320 debugmsg( "set trap %s on top of terrain %s which already has a builit-in trap",
5321 type.obj().name(), ter.name() );
5322 return;
5323 }
5324
5325 // If there was already a trap here, remove it.
5326 if( current_submap->get_trap( l ) != tr_null ) {
5327 remove_trap( p );
5328 }
5329
5330 current_submap->set_trap( l, type );
5331 if( type != tr_null ) {
5332 traplocs[type.to_i()].push_back( p );
5333 }
5334}
void remove_trap(const tripoint &p)
Definition: map.cpp:5394

References debugmsg, get_submap_at(), submap::get_ter(), submap::get_trap(), inbounds(), int_id< T >::obj(), remove_trap(), submap::set_trap(), ter(), tr_null, traplocs, and type.

Referenced by jmapgen_trap::apply(), construct::done_mark_firewood(), construct::done_mark_practice_target(), draw_lab(), mtrap_set(), and MapExtras::mx_portal().

◆ unboard_vehicle() [1/2]

void map::unboard_vehicle ( const tripoint p,
bool  dead_passenger = false 
)

Definition at line 1166 of file map.cpp.

1167{
1168 const std::optional<vpart_reference> vp = veh_at( p ).part_with_feature( VPFLAG_BOARDABLE, false );
1169 player *passenger = nullptr;
1170 if( !vp ) {
1171 debugmsg( "map::unboard_vehicle: vehicle not found" );
1172 // Try and force unboard the player anyway.
1173 passenger = g->critter_at<player>( p );
1174 if( passenger ) {
1175 passenger->in_vehicle = false;
1176 passenger->controlling_vehicle = false;
1177 }
1178 return;
1179 }
1180 passenger = vp->get_passenger();
1181 unboard_vehicle( *vp, passenger, dead_passenger );
1182}
bool controlling_vehicle
Definition: character.h:254

References Character::controlling_vehicle, debugmsg, g, Character::in_vehicle, optional_vpart_position::part_with_feature(), unboard_vehicle(), veh_at(), and VPFLAG_BOARDABLE.

◆ unboard_vehicle() [2/2]

void map::unboard_vehicle ( const vpart_reference vp,
Character passenger,
bool  dead_passenger = false 
)

Definition at line 1146 of file map.cpp.

1147{
1148 // Mark the part as un-occupied regardless of whether there's a live passenger here.
1150 vp.vehicle().invalidate_mass();
1151
1152 if( !passenger ) {
1153 if( !dead_passenger ) {
1154 debugmsg( "map::unboard_vehicle: passenger not found" );
1155 }
1156 return;
1157 }
1158 passenger->in_vehicle = false;
1159 // Only make vehicle go out of control if the driver is the one unboarding.
1160 if( passenger->controlling_vehicle ) {
1161 vp.vehicle().skidding = true;
1162 }
1163 passenger->controlling_vehicle = false;
1164}
void invalidate_mass()
Mark mass caches and pivot cache as dirty.
Definition: vehicle.cpp:6993
vehicle_part & part() const
Yields the vehicle_part object referenced by this.
Definition: vehicle.cpp:6796
::vehicle & vehicle() const

References Character::controlling_vehicle, debugmsg, Character::in_vehicle, vehicle::invalidate_mass(), vpart_reference::part(), vehicle_part::passenger_flag, vehicle_part::remove_flag(), vehicle::skidding, and vpart_reference::vehicle().

Referenced by board_vehicle(), detach_vehicle(), game::fling_creature(), talk_function::individual_mission(), game::is_game_over(), game::moving_vehicle_dismount(), game::phasing_move(), game::place_player(), game::place_player_overmap(), shake_vehicle(), game::swap_critters(), avatar_action::swim(), unboard_vehicle(), and game::vertical_move().

◆ update_lum()

void map::update_lum ( item_location loc,
bool  add 
)

Update luminosity before and after item's transformation.

Definition at line 4567 of file map.cpp.

4568{
4569 item *target = loc.get_item();
4570
4571 // if the item is not emissive, do nothing
4572 if( !target->is_emissive() ) {
4573 return;
4574 }
4575
4576 point l;
4577 submap *const current_submap = get_submap_at( loc.position(), l );
4578
4579 if( add ) {
4580 current_submap->update_lum_add( l, *target );
4581 } else {
4582 current_submap->update_lum_rem( l, *target );
4583 }
4584}
bool is_emissive() const
Whether the item emits any light at all.
Definition: item.cpp:6974

References om_direction::add(), item_location::get_item(), get_submap_at(), item::is_emissive(), item_location::position(), submap::update_lum_add(), and submap::update_lum_rem().

Referenced by update_lum().

◆ update_pathfinding_cache()

void map::update_pathfinding_cache ( int  zlev) const

Definition at line 9004 of file map.cpp.

9005{
9006 auto &cache = get_pathfinding_cache( zlev );
9007 if( !cache.dirty ) {
9008 return;
9009 }
9010
9011 std::uninitialized_fill_n( &cache.special[0][0], MAPSIZE_X * MAPSIZE_Y, PF_NORMAL );
9012
9013 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
9014 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
9015 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
9016 if( !cur_submap ) {
9017 return;
9018 }
9019
9020 tripoint p( 0, 0, zlev );
9021
9022 for( int sx = 0; sx < SEEX; ++sx ) {
9023 p.x = sx + smx * SEEX;
9024 for( int sy = 0; sy < SEEY; ++sy ) {
9025 p.y = sy + smy * SEEY;
9026
9027 pf_special cur_value = PF_NORMAL;
9028
9029 maptile tile( cur_submap, point( sx, sy ) );
9030
9031 const auto &terrain = tile.get_ter_t();
9032 const auto &furniture = tile.get_furn_t();
9033 int part;
9034 const vehicle *veh = veh_at_internal( p, part );
9035
9036 const int cost = move_cost_internal( furniture, terrain, veh, part );
9037
9038 if( cost > 2 ) {
9039 cur_value |= PF_SLOW;
9040 } else if( cost <= 0 ) {
9041 cur_value |= PF_WALL;
9042 if( terrain.has_flag( TFLAG_CLIMBABLE ) ) {
9043 cur_value |= PF_CLIMBABLE;
9044 }
9045 }
9046
9047 if( veh != nullptr ) {
9048 cur_value |= PF_VEHICLE;
9049 }
9050
9051 for( const auto &fld : tile.get_field() ) {
9052 const field_entry &cur = fld.second;
9053 const field_type_id type = cur.get_field_type();
9054 const int field_intensity = cur.get_field_intensity();
9055 if( type.obj().get_dangerous( field_intensity - 1 ) ) {
9056 cur_value |= PF_FIELD;
9057 }
9058 }
9059
9060 if( !tile.get_trap_t().is_benign() || !terrain.trap.obj().is_benign() ) {
9061 cur_value |= PF_TRAP;
9062 }
9063
9064 if( terrain.has_flag( TFLAG_GOES_DOWN ) || terrain.has_flag( TFLAG_GOES_UP ) ||
9065 terrain.has_flag( TFLAG_RAMP ) || terrain.has_flag( TFLAG_RAMP_UP ) ||
9066 terrain.has_flag( TFLAG_RAMP_DOWN ) ) {
9067 cur_value |= PF_UPDOWN;
9068 }
9069
9070 if( terrain.has_flag( TFLAG_SHARP ) ) {
9071 cur_value |= PF_SHARP;
9072 }
9073
9074 cache.special[p.x][p.y] = cur_value;
9075 }
9076 }
9077 }
9078 }
9079
9080 cache.dirty = false;
9081}
@ TFLAG_CLIMBABLE
Definition: mapdata.h:308
@ TFLAG_SHARP
Definition: mapdata.h:297
pf_special
Definition: pathfinding.h:7
@ PF_NORMAL
Definition: pathfinding.h:8
@ PF_FIELD
Definition: pathfinding.h:12

References furniture, maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), get_pathfinding_cache(), get_submap_at_grid(), maptile::get_ter_t(), maptile::get_trap_t(), trap::is_benign(), MAPSIZE_X, MAPSIZE_Y, move_cost_internal(), my_MAPSIZE, PF_CLIMBABLE, PF_FIELD, PF_NORMAL, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, SEEX, SEEY, sx, sy, terrain, TFLAG_CLIMBABLE, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, TFLAG_SHARP, type, veh_at_internal(), tripoint::x, and tripoint::y.

Referenced by get_pathfinding_cache_ref().

◆ update_submap_active_item_status()

void map::update_submap_active_item_status ( const tripoint p)

Definition at line 5727 of file map.cpp.

5728{
5729 point l;
5730 submap *const current_submap = get_submap_at( p, l );
5731 if( current_submap->active_items.empty() ) {
5732 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
5733 }
5734}

References abs_sub, submap::active_items, active_item_cache::empty(), get_submap_at(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

◆ update_suspension_cache()

void map::update_suspension_cache ( const int &  z)

Definition at line 8205 of file map.cpp.

8206{
8207 level_cache &ch = get_cache( z );
8208 if( !ch.suspension_cache_dirty ) {
8209 return;
8210 }
8211 std::list<point> &suspension_cache = ch.suspension_cache;
8213 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8214 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8215 const submap *cur_submap = get_submap_at_grid( { smx, smy, z } );
8216
8217 if( cur_submap == nullptr ) {
8218 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", smx, smy,
8219 z );
8220 continue;
8221 }
8222
8223 for( int sx = 0; sx < SEEX; ++sx ) {
8224 for( int sy = 0; sy < SEEY; ++sy ) {
8225 point sp( sx, sy );
8226 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
8227 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8228 tripoint loc( coords::project_combine( point_om_sm( point( smx, smy ) ), point_sm_ms( sp ) ).raw(),
8229 z );
8230 suspension_cache.emplace_back( getabs( loc ).xy() );
8231 }
8232 }
8233 }
8234 }
8235 }
8237 }
8238
8239 for( auto iter = suspension_cache.begin(); iter != suspension_cache.end(); ) {
8240 const point absp = *iter;
8241 const point locp = getlocal( absp );
8242 const tripoint loctp( locp, z );
8243 if( !inbounds( locp ) ) {
8244 ++iter;
8245 continue;
8246 }
8247 const submap *cur_submap = get_submap_at( loctp );
8248 if( cur_submap == nullptr ) {
8249 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", locp.x,
8250 locp.y, z );
8251 ++iter;
8252 continue;
8253 }
8254 const ter_t &terrain = ter( locp ).obj();
8255 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
8256 if( !is_suspension_valid( loctp ) ) {
8257 support_dirty( loctp );
8258 iter = suspension_cache.erase( iter );
8259 } else {
8260 ++iter;
8261 }
8262 } else {
8263 iter = suspension_cache.erase( iter );
8264 }
8265 }
8266 ch.suspension_cache_dirty = false;
8267}
coords::coord_point< point, coords::origin::overmap, coords::sm > point_om_sm
Definition: coordinates.h:477
auto project_combine(const coord_point< PointL, CoarseOrigin, CoarseScale > &coarse, const coord_point< PointR, FineOrigin, FineScale > &fine)
Definition: coordinates.h:413
bool suspension_cache_initialized
Definition: map.h:310

References debugmsg, get_cache(), get_submap_at(), get_submap_at_grid(), submap::get_ter(), getabs(), getlocal(), inbounds(), is_suspension_valid(), my_MAPSIZE, int_id< T >::obj(), coords::project_combine(), SEEX, SEEY, support_dirty(), level_cache::suspension_cache, level_cache::suspension_cache_dirty, level_cache::suspension_cache_initialized, sx, sy, ter(), terrain, TFLAG_SUSPENDED, point::x, and point::y.

Referenced by build_map_cache().

◆ update_vehicle_cache()

void map::update_vehicle_cache ( vehicle ,
int  old_zlevel 
)

◆ update_vehicle_list()

void map::update_vehicle_list ( const submap to,
int  zlev 
)

Definition at line 400 of file map.cpp.

401{
402 // Update vehicle data
403 level_cache &ch = get_cache( zlev );
404 for( const auto &elem : to->vehicles ) {
405 ch.vehicle_list.insert( elem.get() );
406 if( !elem->loot_zones.empty() ) {
407 ch.zone_vehicles.insert( elem.get() );
408 }
409 }
410
412}

References get_cache(), last_full_vehicle_list_dirty, level_cache::vehicle_list, submap::vehicles, and level_cache::zone_vehicles.

Referenced by displace_vehicle(), rotate(), shift(), and shift_vehicle_z().

◆ update_visibility_cache()

void map::update_visibility_cache ( int  zlev)

Definition at line 5736 of file map.cpp.

5737{
5738 visibility_variables_cache.variables_set = true; // Not used yet
5739 visibility_variables_cache.g_light_level = static_cast<int>( g->light_level( zlev ) );
5740 visibility_variables_cache.vision_threshold = g->u.get_vision_threshold(
5741 get_cache_ref( g->u.posz() ).lm[g->u.posx()][g->u.posy()].max() );
5742
5743 visibility_variables_cache.u_clairvoyance = g->u.clairvoyance();
5744 visibility_variables_cache.u_sight_impaired = g->u.sight_impaired();
5746
5747 int sm_squares_seen[MAPSIZE][MAPSIZE];
5748 std::memset( sm_squares_seen, 0, sizeof( sm_squares_seen ) );
5749
5750 int min_z = fov_3d ? -OVERMAP_DEPTH : zlev;
5751 int max_z = fov_3d ? OVERMAP_HEIGHT : zlev;
5752
5753 for( int z = min_z; z <= max_z; z++ ) {
5754
5755 auto &visibility_cache = get_cache( z ).visibility_cache;
5756
5757 tripoint p;
5758 p.z = z;
5759 int &x = p.x;
5760 int &y = p.y;
5761 for( x = 0; x < MAPSIZE_X; x++ ) {
5762 for( y = 0; y < MAPSIZE_Y; y++ ) {
5764 visibility_cache[x][y] = ll;
5765 if( z == zlev ) {
5766 sm_squares_seen[ x / SEEX ][ y / SEEY ] += ( ll == lit_level::BRIGHT || ll == lit_level::LIT );
5767 }
5768 }
5769 }
5770 }
5771
5772 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
5773 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
5774 if( sm_squares_seen[gridx][gridy] > 36 ) { // 25% of the submap is visible
5775 const tripoint sm( gridx, gridy, 0 );
5776 const auto abs_sm = map::abs_sub + sm;
5777 // TODO: fix point types
5778 const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sm ) );
5779 overmap_buffer.set_seen( abs_omt, true );
5780 }
5781 }
5782 }
5783}
lit_level apparent_light_at(const tripoint &p, const visibility_variables &cache) const
Determine the visible light level for a tile, based on light_at for the tile, vision distance,...
Definition: lightmap.cpp:765
void set_seen(const tripoint_abs_omt &p, bool seen=true)
static const efftype_id effect_boomered("boomered")
bool variables_set
Definition: map.h:122
bool u_sight_impaired
Definition: map.h:123

References abs_sub, apparent_light_at(), BRIGHT, effect_boomered, fov_3d, g, visibility_variables::g_light_level, get_cache(), get_cache_ref(), LIT, level_cache::lm, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, four_quadrants::max(), my_MAPSIZE, overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, overmapbuffer::set_seen(), coords::sm, sm_to_omt_copy(), visibility_variables::u_clairvoyance, visibility_variables::u_is_boomered, visibility_variables::u_sight_impaired, visibility_variables::variables_set, level_cache::visibility_cache, visibility_variables_cache, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw(), draw(), game::get_player_input(), and game::look_around().

◆ use_amount()

std::list< item > map::use_amount ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4940 of file map.cpp.

4942{
4943 std::list<item> ret;
4944 for( int radius = 0; radius <= range && quantity > 0; radius++ ) {
4945 for( const tripoint &p : points_in_radius( origin, radius ) ) {
4946 if( rl_dist( origin, p ) >= radius ) {
4947 std::list<item> tmp = use_amount_square( p, type, quantity, filter );
4948 ret.splice( ret.end(), tmp );
4949 }
4950 }
4951 }
4952 return ret;
4953}
std::list< item > use_amount_square(const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: map.cpp:4918

References points_in_radius(), cata::hash64_detail::ret, rl_dist(), type, and use_amount_square().

◆ use_amount_square()

std::list< item > map::use_amount_square ( const tripoint p,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4918 of file map.cpp.

4920{
4921 std::list<item> ret;
4922 // Handle infinite map sources.
4923 item water = water_from( p );
4924 if( water.typeId() == type ) {
4925 ret.push_back( water );
4926 quantity = 0;
4927 return ret;
4928 }
4929
4930 if( const std::optional<vpart_reference> vp = veh_at( p ).part_with_feature( "CARGO", true ) ) {
4931 std::list<item> tmp = use_amount_stack( vp->vehicle().get_items( vp->part_index() ), type,
4932 quantity, filter );
4933 ret.splice( ret.end(), tmp );
4934 }
4935 std::list<item> tmp = use_amount_stack( i_at( p ), type, quantity, filter );
4936 ret.splice( ret.end(), tmp );
4937 return ret;
4938}
item water_from(const tripoint &p)
Definition: map.cpp:4506
std::list< item > use_amount_stack(Stack stack, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4904

References i_at(), cata::hash64_detail::ret, type, item::typeId(), use_amount_stack(), veh_at(), and water_from().

Referenced by use_amount().

◆ use_charges()

std::list< item > map::use_charges ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item>,
basecamp bcp = nullptr 
)

Definition at line 5038 of file map.cpp.

5041{
5042 std::list<item> ret;
5043
5044 // populate a grid of spots that can be reached
5045 std::vector<tripoint> reachable_pts;
5046 reachable_flood_steps( reachable_pts, origin, range, 1, 100 );
5047
5048 // We prefer infinite map sources where available, so search for those
5049 // first
5050 for( const tripoint &p : reachable_pts ) {
5051 // Handle infinite map sources.
5052 item water = water_from( p );
5053 if( water.typeId() == type ) {
5054 water.charges = quantity;
5055 ret.push_back( water );
5056 quantity = 0;
5057 return ret;
5058 }
5059 }
5060
5061 if( bcp ) {
5062 ret = bcp->use_charges( type, quantity );
5063 if( quantity <= 0 ) {
5064 return ret;
5065 }
5066 }
5067
5068 for( const tripoint &p : reachable_pts ) {
5069 if( has_furn( p ) ) {
5070 use_charges_from_furn( furn( p ).obj(), type, quantity, this, p, ret, filter );
5071 if( quantity <= 0 ) {
5072 return ret;
5073 }
5074 }
5075
5076 if( accessible_items( p ) ) {
5077 std::list<item> tmp = use_charges_from_stack( i_at( p ), type, quantity, p, filter );
5078 ret.splice( ret.end(), tmp );
5079 if( quantity <= 0 ) {
5080 return ret;
5081 }
5082 }
5083
5084 const optional_vpart_position vp = veh_at( p );
5085 if( !vp ) {
5086 continue;
5087 }
5088
5089 const std::optional<vpart_reference> kpart = vp.part_with_feature( "FAUCET", true );
5090 const std::optional<vpart_reference> weldpart = vp.part_with_feature( "WELDRIG", true );
5091 const std::optional<vpart_reference> craftpart = vp.part_with_feature( "CRAFTRIG", true );
5092 const std::optional<vpart_reference> forgepart = vp.part_with_feature( "FORGE", true );
5093 const std::optional<vpart_reference> kilnpart = vp.part_with_feature( "KILN", true );
5094 const std::optional<vpart_reference> chempart = vp.part_with_feature( "CHEMLAB", true );
5095 const std::optional<vpart_reference> autoclavepart = vp.part_with_feature( "AUTOCLAVE", true );
5096 const std::optional<vpart_reference> cargo = vp.part_with_feature( "CARGO", true );
5097
5098 if( kpart ) { // we have a faucet, now to see what to drain
5099 itype_id ftype = itype_id::NULL_ID();
5100
5101 // Special case hotplates which draw battery power
5102 if( type == itype_hotplate ) {
5103 ftype = itype_battery;
5104 } else {
5105 ftype = type;
5106 }
5107
5108 // TODO: add a sane birthday arg
5110 tmp.charges = kpart->vehicle().drain( ftype, quantity );
5111 // TODO: Handle water poison when crafting starts respecting it
5112 quantity -= tmp.charges;
5113 ret.push_back( tmp );
5114
5115 if( quantity == 0 ) {
5116 return ret;
5117 }
5118 }
5119
5120 if( weldpart ) { // we have a weldrig, now to see what to drain
5121 itype_id ftype = itype_id::NULL_ID();
5122
5123 if( type == itype_welder ) {
5124 ftype = itype_battery;
5125 } else if( type == itype_soldering_iron ) {
5126 ftype = itype_battery;
5127 }
5128 // TODO: add a sane birthday arg
5130 tmp.charges = weldpart->vehicle().drain( ftype, quantity );
5131 quantity -= tmp.charges;
5132 ret.push_back( tmp );
5133
5134 if( quantity == 0 ) {
5135 return ret;
5136 }
5137 }
5138
5139 if( craftpart ) { // we have a craftrig, now to see what to drain
5140 itype_id ftype = itype_id::NULL_ID();
5141
5142 if( type == itype_press ) {
5143 ftype = itype_battery;
5144 } else if( type == itype_vac_sealer ) {
5145 ftype = itype_battery;
5146 } else if( type == itype_dehydrator ) {
5147 ftype = itype_battery;
5148 } else if( type == itype_food_processor ) {
5149 ftype = itype_battery;
5150 }
5151
5152 // TODO: add a sane birthday arg
5154 tmp.charges = craftpart->vehicle().drain( ftype, quantity );
5155 quantity -= tmp.charges;
5156 ret.push_back( tmp );
5157
5158 if( quantity == 0 ) {
5159 return ret;
5160 }
5161 }
5162
5163 if( forgepart ) { // we have a veh_forge, now to see what to drain
5164 itype_id ftype = itype_id::NULL_ID();
5165
5166 if( type == itype_forge ) {
5167 ftype = itype_battery;
5168 }
5169
5170 // TODO: add a sane birthday arg
5172 tmp.charges = forgepart->vehicle().drain( ftype, quantity );
5173 quantity -= tmp.charges;
5174 ret.push_back( tmp );
5175
5176 if( quantity == 0 ) {
5177 return ret;
5178 }
5179 }
5180
5181 if( kilnpart ) { // we have a veh_kiln, now to see what to drain
5182 itype_id ftype = itype_id::NULL_ID();
5183
5184 if( type == itype_kiln ) {
5185 ftype = itype_battery;
5186 }
5187
5188 // TODO: add a sane birthday arg
5190 tmp.charges = kilnpart->vehicle().drain( ftype, quantity );
5191 quantity -= tmp.charges;
5192 ret.push_back( tmp );
5193
5194 if( quantity == 0 ) {
5195 return ret;
5196 }
5197 }
5198
5199 if( chempart ) { // we have a chem_lab, now to see what to drain
5200 itype_id ftype = itype_id::NULL_ID();
5201
5202 if( type == itype_chemistry_set ) {
5203 ftype = itype_battery;
5204 } else if( type == itype_hotplate ) {
5205 ftype = itype_battery;
5206 } else if( type == itype_electrolysis_kit ) {
5207 ftype = itype_battery;
5208 }
5209
5210 // TODO: add a sane birthday arg
5212 tmp.charges = chempart->vehicle().drain( ftype, quantity );
5213 quantity -= tmp.charges;
5214 ret.push_back( tmp );
5215
5216 if( quantity == 0 ) {
5217 return ret;
5218 }
5219 }
5220
5221 if( autoclavepart ) { // we have an autoclave, now to see what to drain
5222 itype_id ftype = itype_id::NULL_ID();
5223
5224 if( type == itype_autoclave ) {
5225 ftype = itype_battery;
5226 }
5227
5228 // TODO: add a sane birthday arg
5230 tmp.charges = autoclavepart->vehicle().drain( ftype, quantity );
5231 quantity -= tmp.charges;
5232 ret.push_back( tmp );
5233
5234 if( quantity == 0 ) {
5235 return ret;
5236 }
5237 }
5238
5239 if( cargo ) {
5240 std::list<item> tmp =
5241 use_charges_from_stack( cargo->vehicle().get_items( cargo->part_index() ), type, quantity, p,
5242 filter );
5243 ret.splice( ret.end(), tmp );
5244 if( quantity <= 0 ) {
5245 return ret;
5246 }
5247 }
5248 }
5249
5250 return ret;
5251}
std::list< item > use_charges(const itype_id &fake_id, int &quantity)
Definition: basecamp.cpp:584
bool accessible_items(const tripoint &t) const
Check whether the player can access the items located .
Definition: map.cpp:6696
void reachable_flood_steps(std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
Populates a vector of points that are reachable within a number of steps from a point.
Definition: map.cpp:6425
static const itype_id itype_autoclave("autoclave")
static void use_charges_from_furn(const furn_t &f, const itype_id &type, int &quantity, map *m, const tripoint &p, std::list< item > &ret, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4970
static const itype_id itype_soldering_iron("soldering_iron")
static const itype_id itype_chemistry_set("chemistry_set")
std::list< item > use_charges_from_stack(Stack stack, const itype_id &type, int &quantity, const tripoint &pos, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4956
static const itype_id itype_press("press")
static const itype_id itype_hotplate("hotplate")
static const itype_id itype_electrolysis_kit("electrolysis_kit")
static const itype_id itype_food_processor("food_processor")
static const itype_id itype_forge("forge")
static const itype_id itype_battery("battery")
static const itype_id itype_dehydrator("dehydrator")
static const itype_id itype_kiln("kiln")
static const itype_id itype_welder("welder")
static const itype_id itype_vac_sealer("vac_sealer")

References accessible_items(), item::charges, furn(), has_furn(), i_at(), itype_autoclave, itype_battery, itype_chemistry_set, itype_dehydrator, itype_electrolysis_kit, itype_food_processor, itype_forge, itype_hotplate, itype_kiln, itype_press, itype_soldering_iron, itype_vac_sealer, itype_welder, string_id< itype >::NULL_ID(), optional_vpart_position::part_with_feature(), range, reachable_flood_steps(), cata::hash64_detail::ret, calendar::start_of_cataclysm, type, item::typeId(), basecamp::use_charges(), use_charges_from_furn(), use_charges_from_stack(), veh_at(), and water_from().

Referenced by basecamp_action_components::consume_components(), player::consume_items(), player::consume_tools(), and iexamine::use_furn_fake_item().

◆ valid_move()

bool map::valid_move ( const tripoint from,
const tripoint to,
bool  bash = false,
bool  flying = false,
bool  via_ramp = false 
) const

Returns true if a creature could walk from from to to in one step.

That is, if the tiles are adjacent and either on the same z-level or connected by stairs or (in case of flying monsters) open air with no floors.

Definition at line 1926 of file map.cpp.

1928{
1929 // Used to account for the fact that older versions of GCC can trip on the if statement here.
1930 assert( to.z > std::numeric_limits<int>::min() );
1931 // Note: no need to check inbounds here, because maptile_at will do that
1932 // If oob tile is supplied, the maptile_at will be an unpassable "null" tile
1933 if( std::abs( from.x - to.x ) > 1 || std::abs( from.y - to.y ) > 1 ||
1934 std::abs( from.z - to.z ) > 1 ) {
1935 return false;
1936 }
1937
1938 if( from.z == to.z ) {
1939 // But here we need to, to prevent bashing critters
1940 return passable( to ) || ( bash && inbounds( to ) );
1941 } else if( !zlevels ) {
1942 return false;
1943 }
1944
1945 const bool going_up = from.z < to.z;
1946
1947 const tripoint &up_p = going_up ? to : from;
1948 const tripoint &down_p = going_up ? from : to;
1949
1950 const maptile up = maptile_at( up_p );
1951 const ter_t &up_ter = up.get_ter_t();
1952 if( up_ter.id.is_null() ) {
1953 return false;
1954 }
1955 // Checking for ledge is a workaround for the case when mapgen doesn't
1956 // actually make a valid ledge drop location with zlevels on, this forces
1957 // at least one zlevel drop and if down_ter is impassible it's probably
1958 // inside a wall, we could workaround that further but it's unnecessary.
1959 const bool up_is_ledge = tr_at( up_p ).loadid == tr_ledge;
1960
1961 if( up_ter.movecost == 0 ) {
1962 // Unpassable tile
1963 return false;
1964 }
1965
1966 const maptile down = maptile_at( down_p );
1967 const ter_t &down_ter = down.get_ter_t();
1968 if( down_ter.id.is_null() ) {
1969 return false;
1970 }
1971
1972 if( !up_is_ledge && down_ter.movecost == 0 ) {
1973 // Unpassable tile
1974 return false;
1975 }
1976
1977 if( !up_ter.has_flag( TFLAG_NO_FLOOR ) && !up_ter.has_flag( TFLAG_GOES_DOWN ) && !up_is_ledge &&
1978 !via_ramp ) {
1979 // Can't move from up to down
1980 if( std::abs( from.x - to.x ) == 1 || std::abs( from.y - to.y ) == 1 ) {
1981 // Break the move into two - vertical then horizontal
1982 tripoint midpoint( down_p.xy(), up_p.z );
1983 return valid_move( down_p, midpoint, bash, flying, via_ramp ) &&
1984 valid_move( midpoint, up_p, bash, flying, via_ramp );
1985 }
1986 return false;
1987 }
1988
1989 if( !flying && !down_ter.has_flag( TFLAG_GOES_UP ) && !down_ter.has_flag( TFLAG_RAMP ) &&
1990 !up_is_ledge && !via_ramp ) {
1991 // Can't safely reach the lower tile
1992 return false;
1993 }
1994
1995 if( bash ) {
1996 return true;
1997 }
1998
1999 int part_up;
2000 const vehicle *veh_up = veh_at_internal( up_p, part_up );
2001 if( veh_up != nullptr ) {
2002 // TODO: Hatches below the vehicle, passable frames
2003 return false;
2004 }
2005
2006 int part_down;
2007 const vehicle *veh_down = veh_at_internal( down_p, part_down );
2008 if( veh_down != nullptr && veh_down->roof_at_part( part_down ) >= 0 ) {
2009 // TODO: OPEN (and only open) hatches from above
2010 return false;
2011 }
2012
2013 // Currently only furniture can block movement if everything else is OK
2014 // TODO: Vehicles with boards in the given spot
2015 return up.get_furn_t().movecost >= 0;
2016}
coords::coord_point< Point, Origin, Scale > midpoint(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:562
trap_id loadid
Definition: trap.h:88

References bash(), map_data_common_t::has_flag(), ter_t::id, inbounds(), string_id< T >::is_null(), trap::loadid, maptile_at(), midpoint(), map_data_common_t::movecost, passable(), vehicle::roof_at_part(), TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, tr_at(), tr_ledge, valid_move(), veh_at_internal(), tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by combined_movecost(), draw_critter_internal(), has_floor_or_support(), scent_map::inbounds(), process_fields_in_submap(), route(), spread_gas(), and valid_move().

◆ veh_at() [1/2]

optional_vpart_position map::veh_at ( const tripoint p) const

Checks if tile is occupied by vehicle and by which part.

Parameters
pTile to check for vehicle

Definition at line 1074 of file map.cpp.

1075{
1076 if( !inbounds( p ) || !const_cast<map *>( this )->get_cache( p.z ).veh_in_active_range ) {
1077 return optional_vpart_position( std::nullopt );
1078 }
1079
1080 int part_num = 1;
1081 vehicle *const veh = const_cast<map *>( this )->veh_at_internal( p, part_num );
1082 if( !veh ) {
1083 return optional_vpart_position( std::nullopt );
1084 }
1085 return optional_vpart_position( vpart_position( *veh, part_num ) );
1086
1087}

References get_cache(), inbounds(), veh_at_internal(), level_cache::veh_in_active_range, and tripoint::z.

Referenced by add_splatter(), add_vehicle_to_map(), apply_faction_ownership(), bash(), bash_rating(), bash_vehicle(), board_vehicle(), build_seen_cache(), build_vision_transparency_cache(), VehicleSpawnFunction::builtin_parkinglot(), can_put_items(), can_use_bipod(), climb_difficulty(), doors::close_door(), game::control_vehicle(), coverage(), creature_in_field(), crush(), debug_menu::debug(), deregister_vehicle_zone(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), game::do_turn(), editmap::draw_main_ui_overlay(), drop_vehicle(), game::examine(), game::fling_creature(), game::forced_door_closing(), inventory::form_from_map(), avatar::get_book_reader(), game::get_dangerous_tile(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), game::get_veh_dir_indicator_location(), game::grabbed_furn_move(), game::grabbed_veh_move(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), game::handle_action(), has_flag_vpart(), has_nearby_chair(), has_nearby_table(), jmapgen_setmap::has_vehicle_collision(), mapgen_function_json_base::has_vehicle_collision(), jmapgen_alternativly< PieceType >::has_vehicle_collision(), jmapgen_sign::has_vehicle_collision(), jmapgen_vending_machine::has_vehicle_collision(), jmapgen_toilet::has_vehicle_collision(), jmapgen_gaspump::has_vehicle_collision(), jmapgen_vehicle::has_vehicle_collision(), jmapgen_trap::has_vehicle_collision(), jmapgen_furniture::has_vehicle_collision(), jmapgen_terrain::has_vehicle_collision(), jmapgen_computer::has_vehicle_collision(), jmapgen_sealed_item::has_vehicle_collision(), is_bashable(), is_driving(), weather::is_sheltered(), game::load(), monster_in_field(), mop_spills(), avatar_action::move(), move_cost(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_helicopter(), obstacle_coverage(), obstacle_name(), open_door(), game::phasing_move(), game::place_player(), player_in_field(), game::print_all_tile_info(), game::remoteveh(), conditional_t< T >::set_is_driving(), shoot(), autodrive_activity_actor::start(), supports_above(), game::swap_critters(), avatar_action::swim(), rot::temperature_flag_for_location(), unboard_vehicle(), Character::update_bodytemp(), use_amount_square(), use_charges(), game::validate_linked_vehicles(), veh_at(), and game::walk_move().

◆ veh_at() [2/2]

optional_vpart_position map::veh_at ( const tripoint_abs_ms p) const

Definition at line 1069 of file map.cpp.

1070{
1071 return veh_at( getlocal( p ) );
1072}

References getlocal(), and veh_at().

◆ veh_at_internal() [1/2]

vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
)

Definition at line 1109 of file map.cpp.

1110{
1111 return const_cast<vehicle *>( const_cast<const map *>( this )->veh_at_internal( p, part_num ) );
1112}

References veh_at_internal().

Referenced by draw_from_above(), draw_maptile(), process_fields_in_submap(), route(), update_pathfinding_cache(), valid_move(), veh_at(), and veh_at_internal().

◆ veh_at_internal() [2/2]

const vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
) const

Definition at line 1089 of file map.cpp.

1090{
1091 // This function is called A LOT. Move as much out of here as possible.
1092 const level_cache &ch = get_cache( p.z );
1093 if( !ch.veh_in_active_range || !ch.veh_exists_at[p.x][p.y] ) {
1094 part_num = -1;
1095 return nullptr; // Clear cache indicates no vehicle. This should optimize a great deal.
1096 }
1097
1098 const auto it = ch.veh_cached_parts.find( p );
1099 if( it != ch.veh_cached_parts.end() ) {
1100 part_num = it->second.second;
1101 return it->second.first;
1102 }
1103
1104 debugmsg( "vehicle part cache indicated vehicle not found: %d %d %d", p.x, p.y, p.z );
1105 part_num = -1;
1106 return nullptr;
1107}

References debugmsg, get_cache(), level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

◆ vehicle_vehicle_collision()

float map::vehicle_vehicle_collision ( vehicle veh,
vehicle veh2,
const std::vector< veh_collision > &  collisions 
)

Definition at line 822 of file map.cpp.

824{
825 if( &veh == &veh2 ) {
826 debugmsg( "Vehicle %s collided with itself", veh.name );
827 return 0.0f;
828 }
829
830 // Effects of colliding with another vehicle:
831 // transfers of momentum, skidding,
832 // parts are damaged/broken on both sides,
833 // remaining times are normalized
834 const veh_collision &c = collisions[0];
835 add_msg( m_bad, _( "The %1$s's %2$s collides with %3$s's %4$s." ),
836 veh.name, veh.part_info( c.part ).name(),
837 veh2.name, veh2.part_info( c.target_part ).name() );
838
839 const bool vertical = veh.sm_pos.z != veh2.sm_pos.z;
840
841 // Used to calculate the epicenter of the collision.
842 point epicenter1;
843 point epicenter2;
844
845 float dmg;
846 // Vertical collisions will be simpler for a while (1D)
847 if( !vertical ) {
848 // For reference, a cargo truck weighs ~25300, a bicycle 690,
849 // and 38mph is 3800 'velocity'
850 rl_vec2d velo_veh1 = veh.velo_vec();
851 rl_vec2d velo_veh2 = veh2.velo_vec();
852 const float m1 = to_kilogram( veh.total_mass() );
853 const float m2 = to_kilogram( veh2.total_mass() );
854 //Energy of vehicle1 and vehicle2 before collision
855 float E = 0.5 * m1 * velo_veh1.magnitude() * velo_veh1.magnitude() +
856 0.5 * m2 * velo_veh2.magnitude() * velo_veh2.magnitude();
857
858 // Collision_axis
859 point cof1 = veh .rotated_center_of_mass();
860 point cof2 = veh2.rotated_center_of_mass();
861 int &x_cof1 = cof1.x;
862 int &y_cof1 = cof1.y;
863 int &x_cof2 = cof2.x;
864 int &y_cof2 = cof2.y;
865 rl_vec2d collision_axis_y;
866
867 collision_axis_y.x = ( veh.global_pos3().x + x_cof1 ) - ( veh2.global_pos3().x + x_cof2 );
868 collision_axis_y.y = ( veh.global_pos3().y + y_cof1 ) - ( veh2.global_pos3().y + y_cof2 );
869 collision_axis_y = collision_axis_y.normalized();
870 rl_vec2d collision_axis_x = collision_axis_y.rotated( M_PI / 2 );
871 // imp? & delta? & final? reworked:
872 // newvel1 =( vel1 * ( mass1 - mass2 ) + ( 2 * mass2 * vel2 ) ) / ( mass1 + mass2 )
873 // as per http://en.wikipedia.org/wiki/Elastic_collision
874 //velocity of veh1 before collision in the direction of collision_axis_y
875 float vel1_y = collision_axis_y.dot_product( velo_veh1 );
876 float vel1_x = collision_axis_x.dot_product( velo_veh1 );
877 //velocity of veh2 before collision in the direction of collision_axis_y
878 float vel2_y = collision_axis_y.dot_product( velo_veh2 );
879 float vel2_x = collision_axis_x.dot_product( velo_veh2 );
880 // e = 0 -> inelastic collision
881 // e = 1 -> elastic collision
882 float e = get_collision_factor( vel1_y / 100 - vel2_y / 100 );
883
884 // Velocity after collision
885 // vel1_x_a = vel1_x, because in x-direction we have no transmission of force
886 float vel1_x_a = vel1_x;
887 float vel2_x_a = vel2_x;
888 // Transmission of force only in direction of collision_axix_y
889 // Equation: partially elastic collision
890 float vel1_y_a = ( m2 * vel2_y * ( 1 + e ) + vel1_y * ( m1 - m2 * e ) ) / ( m1 + m2 );
891 float vel2_y_a = ( m1 * vel1_y * ( 1 + e ) + vel2_y * ( m2 - m1 * e ) ) / ( m1 + m2 );
892 // Add both components; Note: collision_axis is normalized
893 rl_vec2d final1 = collision_axis_y * vel1_y_a + collision_axis_x * vel1_x_a;
894 rl_vec2d final2 = collision_axis_y * vel2_y_a + collision_axis_x * vel2_x_a;
895
896 veh.move.init( final1.as_point() );
897 if( final1.dot_product( veh.face_vec() ) < 0 ) {
898 // Car is being pushed backwards. Make it move backwards
899 veh.velocity = -final1.magnitude();
900 } else {
901 veh.velocity = final1.magnitude();
902 }
903
904 veh2.move.init( final2.as_point() );
905 if( final2.dot_product( veh2.face_vec() ) < 0 ) {
906 // Car is being pushed backwards. Make it move backwards
907 veh2.velocity = -final2.magnitude();
908 } else {
909 veh2.velocity = final2.magnitude();
910 }
911
912 //give veh2 the initiative to proceed next before veh1
913 float avg_of_turn = ( veh2.of_turn + veh.of_turn ) / 2;
914 if( avg_of_turn < .1f ) {
915 avg_of_turn = .1f;
916 }
917
918 veh.of_turn = avg_of_turn * .9;
919 veh2.of_turn = avg_of_turn * 1.1;
920
921 //Energy after collision
922 float E_a = 0.5 * m1 * final1.magnitude() * final1.magnitude() +
923 0.5 * m2 * final2.magnitude() * final2.magnitude();
924 float d_E = E - E_a; //Lost energy at collision -> deformation energy
925 dmg = std::abs( d_E / 1000 / 2000 ); //adjust to balance damage
926 } else {
927 const float m1 = to_kilogram( veh.total_mass() );
928 // Collision is perfectly inelastic for simplicity
929 // Assume veh2 is standing still
930 dmg = std::abs( veh.vertical_velocity / 100 ) * m1 / 10;
931 veh.vertical_velocity = 0;
932 }
933
934 float dmg_veh1 = dmg * 0.5;
935 float dmg_veh2 = dmg * 0.5;
936
937 int coll_parts_cnt = 0; //quantity of colliding parts between veh1 and veh2
938 for( const auto &veh_veh_coll : collisions ) {
939 if( &veh2 == static_cast<vehicle *>( veh_veh_coll.target ) ) {
940 coll_parts_cnt++;
941 }
942 }
943
944 const float dmg1_part = dmg_veh1 / coll_parts_cnt;
945 const float dmg2_part = dmg_veh2 / coll_parts_cnt;
946
947 //damage colliding parts (only veh1 and veh2 parts)
948 for( const auto &veh_veh_coll : collisions ) {
949 if( &veh2 != static_cast<vehicle *>( veh_veh_coll.target ) ) {
950 continue;
951 }
952
953 int parm1 = veh.part_with_feature( veh_veh_coll.part, VPFLAG_ARMOR, true );
954 if( parm1 < 0 ) {
955 parm1 = veh_veh_coll.part;
956 }
957 int parm2 = veh2.part_with_feature( veh_veh_coll.target_part, VPFLAG_ARMOR, true );
958 if( parm2 < 0 ) {
959 parm2 = veh_veh_coll.target_part;
960 }
961
962 epicenter1 += veh.part( parm1 ).mount;
963 veh.damage( parm1, dmg1_part, DT_BASH );
964
965 epicenter2 += veh2.part( parm2 ).mount;
966 veh2.damage( parm2, dmg2_part, DT_BASH );
967 }
968
969 epicenter2.x /= coll_parts_cnt;
970 epicenter2.y /= coll_parts_cnt;
971
972 if( dmg2_part > 100 ) {
973 // Shake vehicle because of collision
974 veh2.damage_all( dmg2_part / 2, dmg2_part, DT_BASH, epicenter2 );
975 }
976
977 if( dmg_veh1 > 800 ) {
978 veh.skidding = true;
979 }
980
981 if( dmg_veh2 > 800 ) {
982 veh2.skidding = true;
983 }
984
985 // Return the impulse of the collision
986 return dmg_veh1;
987}
point rotated_center_of_mass() const
Definition: vehicle.cpp:3329
rl_vec2d face_vec() const
rl_vec2d velo_vec() const
float of_turn
Definition: vehicle.h:1663
std::string name() const
Translated name of a part.
Definition: veh_type.cpp:701
#define M_PI
Definition: math_defines.h:21
point as_point() const
Definition: line.cpp:689
rl_vec2d rotated(float angle) const
Definition: line.cpp:650
float magnitude() const
Definition: line.cpp:613
rl_vec2d normalized() const
Definition: line.cpp:623
float y
Definition: point_float.h:13
float x
Definition: point_float.h:12
float dot_product(const rl_vec2d &v) const
Definition: line.cpp:667
@ VPFLAG_ARMOR
Definition: veh_type.h:32
float get_collision_factor(float delta_v)

References _, add_msg(), rl_vec2d::as_point(), c, vehicle::damage(), vehicle::damage_all(), debugmsg, rl_vec2d::dot_product(), DT_BASH, vehicle::face_vec(), get_collision_factor(), vehicle::global_pos3(), tileray::init(), m_bad, M_PI, rl_vec2d::magnitude(), vehicle_part::mount, vehicle::move, vpart_info::name(), vehicle::name, rl_vec2d::normalized(), vehicle::of_turn, vehicle::part(), vehicle::part_info(), vehicle::part_with_feature(), rl_vec2d::rotated(), vehicle::rotated_center_of_mass(), vehicle::skidding, vehicle::sm_pos, units::to_kilogram(), vehicle::total_mass(), vehicle::velo_vec(), vehicle::velocity, vehicle::vertical_velocity, VPFLAG_ARMOR, point::x, tripoint::x, rl_vec2d::x, point::y, tripoint::y, rl_vec2d::y, and tripoint::z.

Referenced by move_vehicle().

◆ vehicle_wheel_traction()

float map::vehicle_wheel_traction ( const vehicle veh,
bool  ignore_movement_modifiers = false 
) const

Definition at line 1587 of file vehicle_move.cpp.

1589{
1590 if( veh.is_in_water( true ) ) {
1591 return veh.can_float() ? 1.0f : -1.0f;
1592 }
1593 if( veh.is_in_water() && veh.is_watercraft() && veh.can_float() ) {
1594 return 1.0f;
1595 }
1596
1597 const auto &wheel_indices = veh.wheelcache;
1598 int num_wheels = wheel_indices.size();
1599 if( num_wheels == 0 ) {
1600 // TODO: Assume it is digging in dirt
1601 // TODO: Return something that could be reused for dragging
1602 return 0.0f;
1603 }
1604
1605 float traction_wheel_area = 0.0f;
1606
1607 if( vehicle_movement::is_on_rails( *this, veh ) ) {
1608 // Vehicles on rails are considered to have all of their wheels on rails
1609 for( int p : veh.rail_wheelcache ) {
1610 traction_wheel_area += veh.cpart( p ).wheel_area();
1611 }
1612 return traction_wheel_area;
1613 }
1614
1615 for( int p : wheel_indices ) {
1616 const tripoint &pp = veh.global_part_pos3( p );
1617 const int wheel_area = veh.cpart( p ).wheel_area();
1618
1619 const auto &tr = ter( pp ).obj();
1620 // Deep water and air
1621 if( tr.has_flag( TFLAG_DEEP_WATER ) || tr.has_flag( TFLAG_NO_FLOOR ) ) {
1622 // No traction from wheel in water or air
1623 continue;
1624 }
1625
1626 int move_mod = move_cost_ter_furn( pp );
1627 if( move_mod == 0 ) {
1628 // Vehicle locked in wall
1629 // Shouldn't happen, but does
1630 return 0.0f;
1631 }
1632
1633 for( const auto &terrain_mod : veh.part_info( p ).wheel_terrain_mod() ) {
1634 if( !tr.has_flag( terrain_mod.first ) ) {
1635 move_mod += terrain_mod.second;
1636 break;
1637 }
1638 }
1639
1640 // Ignore the movement modifier if needed.
1641 if( ignore_movement_modifiers ) {
1642 move_mod = 2;
1643 }
1644
1645 traction_wheel_area += 2.0 * wheel_area / move_mod;
1646 }
1647
1648 return traction_wheel_area;
1649}
bool is_watercraft() const
Definition: vehicle.cpp:4239
std::vector< int > rail_wheelcache
Definition: vehicle.h:1552
bool can_float() const
can_float does the vehicle have freeboard or does it overflow with water?
Definition: vehicle.cpp:4176
std::vector< std::pair< std::string, int > > wheel_terrain_mod() const
Definition: veh_type.cpp:899
bool is_on_rails(const map &m, const vehicle &veh)
Returns whether the vehicle is currently on rails.

References vehicle::can_float(), vehicle::cpart(), vehicle::global_part_pos3(), vehicle::is_in_water(), vehicle_movement::is_on_rails(), vehicle::is_watercraft(), move_cost_ter_furn(), int_id< T >::obj(), vehicle::part_info(), vehicle::rail_wheelcache, ter(), TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, vehicle_part::wheel_area(), vpart_info::wheel_terrain_mod(), and vehicle::wheelcache.

Referenced by move_vehicle().

◆ vehmove()

void map::vehmove ( )

Definition at line 474 of file map.cpp.

475{
476 // give vehicles movement points
477 VehicleList vehicle_list;
478 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
479 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
480 for( int zlev = minz; zlev <= maxz; ++zlev ) {
481 level_cache &cache = get_cache( zlev );
482 for( vehicle *veh : cache.vehicle_list ) {
483 veh->gain_moves();
484 veh->slow_leak();
486 w.v = veh;
487 vehicle_list.push_back( w );
488 }
489 }
490
491 // 15 equals 3 >50mph vehicles, or up to 15 slow (1 square move) ones
492 // But 15 is too low for V12 death-bikes, let's put 100 here
493 for( int count = 0; count < 100; count++ ) {
494 if( !vehproceed( vehicle_list ) ) {
495 break;
496 }
497 }
498 // Process item removal on the vehicles that were modified this turn.
499 // Use a copy because part_removal_cleanup can modify the container.
500 auto temp = dirty_vehicle_list;
501 for( const auto &elem : temp ) {
502 auto same_ptr = [ elem ]( const struct wrapped_vehicle & tgt ) {
503 return elem == tgt.v;
504 };
505 if( std::find_if( vehicle_list.begin(), vehicle_list.end(), same_ptr ) !=
506 vehicle_list.end() ) {
507 elem->part_removal_cleanup();
508 }
509 }
510 dirty_vehicle_list.clear();
511 // The bool tracks whether the vehicles is on the map or not.
512 std::map<vehicle *, bool> connected_vehicles;
513 for( int zlev = minz; zlev <= maxz; ++zlev ) {
514 level_cache &cache = get_cache( zlev );
515 vehicle::enumerate_vehicles( connected_vehicles, cache.vehicle_list );
516 }
517 for( std::pair<vehicle *const, bool> &veh_pair : connected_vehicles ) {
518 veh_pair.first->idle( veh_pair.second );
519 }
520}
bool vehproceed(VehicleList &vehicle_list)
Definition: map.cpp:522
static void enumerate_vehicles(std::map< vehicle *, bool > &connected_vehicles, const std::set< vehicle * > &vehicle_list)
Use grid traversal to enumerate all connected vehicles.
Definition: vehicle.cpp:4950
void slow_leak()
Definition: vehicle.cpp:5317
void gain_moves()
Definition: vehicle.cpp:5564

References abs_sub, detail::count(), dirty_vehicle_list, vehicle::enumerate_vehicles(), vehicle::gain_moves(), get_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::slow_leak(), wrapped_vehicle::v, level_cache::vehicle_list, vehproceed(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ vehproceed()

bool map::vehproceed ( VehicleList vehicle_list)

Definition at line 522 of file map.cpp.

523{
524 wrapped_vehicle *cur_veh = nullptr;
525 float max_of_turn = 0;
526 // First horizontal movement
527 for( wrapped_vehicle &vehs_v : vehicle_list ) {
528 if( vehs_v.v->of_turn > max_of_turn ) {
529 cur_veh = &vehs_v;
530 max_of_turn = cur_veh->v->of_turn;
531 }
532 }
533
534 // Then vertical-only movement
535 if( cur_veh == nullptr ) {
536 for( wrapped_vehicle &vehs_v : vehicle_list ) {
537 if( vehs_v.v->is_falling || ( vehs_v.v->is_rotorcraft() && vehs_v.v->get_z_change() != 0 ) ) {
538 cur_veh = &vehs_v;
539 break;
540 }
541 }
542 }
543
544 if( cur_veh == nullptr ) {
545 return false;
546 }
547
548 cur_veh->v = cur_veh->v->act_on_map();
549 if( cur_veh->v == nullptr ) {
550 vehicle_list = get_vehicles();
551 }
552
553 // confirm that veh_in_active_range is still correct for each z-level
554 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
555 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
556 for( int zlev = minz; zlev <= maxz; ++zlev ) {
557 level_cache &cache = get_cache( zlev );
558
559 // Check if any vehicles exist in the active range for this z-level
561 std::any_of( std::begin( cache.veh_exists_at ),
562 std::end( cache.veh_exists_at ), []( const auto & row ) {
563 return std::any_of( std::begin( row ), std::end( row ), []( bool veh_exists ) {
564 return veh_exists;
565 } );
566 } );
567 }
568
569 return true;
570}
vehicle * act_on_map()

References abs_sub, vehicle::act_on_map(), get_cache(), get_vehicles(), vehicle::of_turn, OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::v, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by vehmove().

◆ vertical_shift()

void map::vertical_shift ( int  newz)

Moves the map vertically to (not by!) newz.

Does not actually shift anything, only forces cache updates. In the future, it will either actually shift the map or it will get removed after 3D migration is complete.

Definition at line 7050 of file map.cpp.

7051{
7052 if( !zlevels ) {
7053 debugmsg( "Called map::vertical_shift in a non-z-level world" );
7054 return;
7055 }
7056
7057 if( newz < -OVERMAP_DEPTH || newz > OVERMAP_HEIGHT ) {
7058 debugmsg( "Tried to get z-level %d outside allowed range of %d-%d",
7059 newz, -OVERMAP_DEPTH, OVERMAP_HEIGHT );
7060 return;
7061 }
7062
7063 tripoint trp = get_abs_sub();
7064 set_abs_sub( tripoint( trp.xy(), newz ) );
7065
7066 // TODO: Remove the function when it's safe
7067 return;
7068}

References debugmsg, get_abs_sub(), OVERMAP_DEPTH, OVERMAP_HEIGHT, set_abs_sub(), tripoint::xy(), and zlevels.

Referenced by game::vertical_shift().

◆ water_from()

item map::water_from ( const tripoint p)

Definition at line 4506 of file map.cpp.

4507{
4508 if( has_flag( "SALT_WATER", p ) ) {
4510 }
4511
4512 const ter_id terrain_id = ter( p );
4513 if( terrain_id == t_sewage ) {
4515 ret.poison = rng( 1, 7 );
4516 return ret;
4517 }
4518
4520 // iexamine::water_source requires a valid liquid from this function.
4521 if( terrain_id.obj().examine == &iexamine::water_source ) {
4522 int poison_chance = 0;
4523 if( terrain_id.obj().has_flag( TFLAG_DEEP_WATER ) ) {
4524 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4525 poison_chance = 20;
4526 } else {
4527 poison_chance = 4;
4528 }
4529 } else {
4530 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4531 poison_chance = 10;
4532 } else {
4533 poison_chance = 3;
4534 }
4535 }
4536 if( one_in( poison_chance ) ) {
4537 ret.poison = rng( 1, 4 );
4538 }
4539 return ret;
4540 }
4541 if( furn( p ).obj().examine == &iexamine::water_source ) {
4542 return ret;
4543 }
4544 return item();
4545}
static const int INFINITE_CHARGES
Definition: item.h:2168
void examine(Character &p, const tripoint &pos)
Calls the examine function of furniture or terrain at given tile, for given character.
Definition: map.cpp:1685
@ TFLAG_CURRENT
Definition: mapdata.h:303
void water_source(player &p, const tripoint &examp)
Definition: iexamine.cpp:3787

References examine(), map_data_common_t::examine, furn(), map_data_common_t::has_flag(), has_flag(), item::INFINITE_CHARGES, int_id< T >::obj(), one_in(), cata::hash64_detail::ret, rng(), calendar::start_of_cataclysm, t_sewage, ter(), TFLAG_CURRENT, TFLAG_DEEP_WATER, and iexamine::water_source().

Referenced by inventory::form_from_map(), use_amount_square(), and use_charges().

Friends And Related Function Documentation

◆ editmap

friend class editmap
friend

Definition at line 385 of file map.h.

◆ visitable< map_cursor >

friend class visitable< map_cursor >
friend

Definition at line 385 of file map.h.

Member Data Documentation

◆ abs_sub

tripoint map::abs_sub
protected

Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation).

It is set upon:

  • loading submap at grid[0],
  • generating submaps (generate)
  • shifting the map with shift

Definition at line 1801 of file map.h.

Referenced by add_item(), add_item_or_charges(), add_vehicle(), adjust_radiation(), apply_faction_ownership(), bash_rating(), bash_resistance(), bash_strength(), build_floor_caches(), can_put_items(), can_put_items_ter_furn(), check_submap_active_item_consistency(), clear_vehicle_cache(), create_anomaly(), decay_fields_and_scent(), detach_vehicle(), draw_fill_background(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), features(), furn(), furn_set(), furnname(), generate(), get_abs_sub(), get_active_items_in_radius(), get_nonant(), get_submap_at(), get_vehicles(), getabs(), getlocal(), has_flag(), has_flag_furn(), has_flag_ter(), has_flag_ter_or_furn(), has_furn(), i_at(), i_clear(), i_rem(), is_bashable(), is_bashable_furn(), is_bashable_ter(), is_bashable_ter_furn(), is_divable(), is_outside(), is_water_shallow_current(), loadn(), make_active(), move_cost(), move_cost_ter_furn(), name(), passable(), place_items(), place_npc(), place_vending(), points_on_zlevel(), process_fields(), process_fields_in_submap(), process_items(), reset_vehicle_cache(), rotate(), save(), saven(), scent_blockers(), set_abs_sub(), set_radiation(), set_temperature(), spawn_an_item(), spawn_item(), spawn_items(), spawn_monsters(), spawn_monsters_submap(), spawn_monsters_submap_group(), ter(), ter_set(), tername(), update_submap_active_item_status(), update_visibility_cache(), vehmove(), and vehproceed().

◆ caches

std::array< std::unique_ptr<level_cache>, OVERMAP_LAYERS > map::caches
private

Holds caches for visibility, light, transparency and vehicles.

Definition at line 1973 of file map.h.

Referenced by access_cache(), get_cache(), get_cache_ref(), and map().

◆ dirty_vehicle_list

std::set<vehicle *> map::dirty_vehicle_list

Definition at line 1600 of file map.h.

Referenced by detach_vehicle(), loadn(), MapgenRemovePartHandler::removed(), and vehmove().

◆ field_furn_locs

std::vector<tripoint> map::field_furn_locs
private

Vector of tripoints containing active field-emitting furniture.

Definition at line 1969 of file map.h.

Referenced by actualize(), furn_set(), get_furn_field_locations(), load(), and shift_traps().

◆ grid

std::vector<submap *> map::grid
private

The list of currently loaded submaps.

The size of this should not be changed. After calling load or generate, it should only contain non-null pointers. Use getsubmap or setsubmap to access it.

Definition at line 1958 of file map.h.

Referenced by actualize(), add_roofs(), clear_spawns(), clear_traps(), editmap::cleartmpmap(), displace_vehicle(), getsubmap(), loadn(), map(), saven(), and setsubmap().

◆ last_full_vehicle_list

VehicleList map::last_full_vehicle_list
private

Vehicle list doesn't change often, but is pretty expensive.

Definition at line 1989 of file map.h.

Referenced by get_vehicles().

◆ last_full_vehicle_list_dirty

bool map::last_full_vehicle_list_dirty = true
private

◆ max_populated_zlev

std::optional<std::pair<tripoint, int> > map::max_populated_zlev = std::nullopt
private

Definition at line 2003 of file map.h.

Referenced by calc_max_populated_zlev(), and invalidate_max_populated_zlev().

◆ my_MAPSIZE

◆ pathfinding_caches

std::array< std::unique_ptr<pathfinding_cache>, OVERMAP_LAYERS > map::pathfinding_caches
mutableprivate

Definition at line 1975 of file map.h.

Referenced by get_pathfinding_cache(), get_pathfinding_cache_ref(), and map().

◆ skew_vision_cache

lru_cache<point, char> map::skew_vision_cache
mutableprivate

Cache of coordinate pairs recently checked for visibility.

Definition at line 1984 of file map.h.

Referenced by build_map_cache(), and sees().

◆ submaps_with_active_items

std::set<tripoint> map::submaps_with_active_items
private

◆ support_cache_dirty

std::set<tripoint> map::support_cache_dirty
private

Definition at line 1499 of file map.h.

Referenced by process_falling(), shift(), support_dirty(), and ter_set().

◆ traplocs

std::vector< std::vector<tripoint> > map::traplocs
private

This vector contains an entry for each trap type, it has therefor the same size as the traplist vector.

Each entry contains a list of all point on the map that contain a trap of that type. The first entry however is always empty as it denotes the tr_null trap.

Definition at line 1965 of file map.h.

Referenced by actualize(), clear_traps(), load(), map(), remove_trap(), shift_traps(), ter_set(), trap_locations(), and trap_set().

◆ visibility_variables_cache

visibility_variables map::visibility_variables_cache
private

Definition at line 1999 of file map.h.

Referenced by get_visibility_variables_cache(), and update_visibility_cache().

◆ vision_transparency_cache

vision_adjustment map::vision_transparency_cache[8] = { VISION_ADJUST_NONE }
protected

Definition at line 1791 of file map.h.

Referenced by apply_vision_transparency_cache(), and build_vision_transparency_cache().

◆ zlevels


The documentation for this class was generated from the following files: